Esistono differenze tra un canale Go e un Java BlockingQueue? Entrambe sono code con una simile semantica di blocco e memoria. Opzionalmente entrambi possono avere un set di capacità.Go channel vs Java BlockingQueue
risposta
Direi che la più grande differenza è che i canali Go hanno il supporto per il select
dichiarazione, che consentono di eseguire esattamente un funzionamento del canale. Un esempio (alterata dalla Go language specification):
select {
case i1 = <-c1:
print("received ", i1, " from c1\n")
case c2 <- i2:
print("sent ", i2, " to c2\n")
case i3, ok := (<-c3): // same as: i3, ok := <-c3
if ok {
print("received ", i3, " from c3\n")
} else {
print("c3 is closed\n")
}
}
In questo esempio, esattamente una delle operazioni di ricezione-da-c1, invia-to-c2, o ricevere-da-c3 viene eseguita. Quando si entra nella selezione, un canale pronto (se presente) viene selezionato casualmente. Altrimenti, l'operazione si blocca fino a quando uno dei canali è pronto.
Non sono a conoscenza di alcun modo banale per modellare questa selezione di canali utilizzando le utilità Java. Si potrebbe sostenere che questa è una proprietà della dichiarazione select
piuttosto che la progettazione di canali, ma direi che è fondamentale per la progettazione dei canali.
Possono essere utilizzati in modi simili.
- Entrambi possono bloccare quando si inserisce/invia o si prende/riceve.
- Entrambi hanno una capacità che governa quando l'invio verrà bloccato.
Le maggiori differenze sono probabilmente che i canali di go sono considerevolmente più economici di un oggetto java. e che i canali di go possono essere limitati a solo inviare o ricevere solo in grado di garantire alcune imposizioni di tipo aggiuntive per quanto riguarda chi può inviare e chi può ricevere da un canale.
Hai qualche fonte per dimostrare che sono molto più economici? Non è che non ti creda, ma non sarei sorpreso se alcune delle code e dei canali nio di Java fossero in grado di tenere il passo dei tempi di esecuzione. Sono sicuro che Java si perde sul fronte della memoria però. –
@AdamGent Ho paura di non avere risorse a portata di mano. Stavo principalmente parlando di memoria, ma non di velocità di esecuzione. –
Per fare qualcosa di simile all'istruzione golang'select in java si prevede l'utilizzo del pacchetto java.nio. Specificamente selettori e canali. Controlla la documentazione del pacchetto qui:
http://docs.oracle.com/javase/6/docs/api/java/nio/channels/package-summary.html#multiplex
offre praticamente la stessa capacità come l'istruzione select golang, utilizzando un singolo thread di multiplex lettura/scrittura da più canali.
I canali Go consentono di trasferire strutture di dati arbitrarie (inclusi i puntatori), ma java.nio.channels consente solo il trasferimento dei byte. Non penso che siano davvero comparabili. –
Un'altra differenza molto importante è la seguente: è possibile chiudere un canale Go per segnalare che non vi sono più elementi in arrivo. Questo non è possibile usando Java.
Esempio: goroutine A legge un elenco di file. Pubblica ogni file nel canale. Dopo l'ultimo file, chiude il canale. goroutine B legge i file dal canale e li elabora in qualche modo. Dopo che il canale è stato chiuso, la goroutine si chiude.
Fare questo in Java non è facilmente possibile; tuttavia esistono alcuni soluzioni alternative.
Davvero! Questa è una differenza molto importante. Con Java, devi inviare qualche tipo di record veleno o carattere di fine flusso per segnalare che non ci saranno altri elementi in arrivo. Ciò richiede codice aggiuntivo su entrambi i lati, vedi [javadoc di BlockingQueue] (https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html): 'una tattica comune è per i produttori di inserire oggetti speciali di fine flusso o veleno, che vengono interpretati di conseguenza quando vengono presi dai consumatori –
- 1. Java BlockingQueue take() vs poll()
- 2. Java NIO Pipe vs BlockingQueue
- 3. Android Looper vs BlockingQueue?
- 4. Java BlockingQueue con il batching?
- 5. È BlockingQueue completamente thread-safe in Java
- 6. C++ Equivalente a Java's BlockingQueue
- 7. BlockingQueue - blocked drainTo() methods
- 8. Rilevazione chiusa Netty Channel
- 9. Java: ArrayBlockingQueue vs. LinkedBlockingQueue
- 10. Qual è la differenza tra Android Studio Beta Channel, Android Studio Canary Channel, Android Studio Dev Channel?
- 11. WCF Channel e ChannelFactory Caching
- 12. Netty Increase Channel Dimensione buffer
- 13. WCF Duplex Service Channel Close
- 14. ANTLR 4 $ channel = HIDDEN e opzioni
- 15. Go Code si comporta in modo diverso in go test vs go run
- 16. come usare java con go
- 17. tasto Go vs if-else efficienza
- 18. Uso di new vs var in Go
- 19. blocco Go vs thread nel core.async
- 20. Cache Channel Service - Tridion 2011 SP1
- 21. Impossibile creare SSL/TLS Secure Channel
- 22. Go ha qualcosa come ThreadLocal da Java?
- 23. Porting Java App to Go - qualche consiglio?
- 24. google go equivalente del metodo java finalize
- 25. Come bloccare fino a quando un BlockingQueue è vuoto?
- 26. cosa è equivalente a <tcp-outbound-channel-adapter> in java config?
- 27. Mappa di struct vs array di struct in Go
- 28. Struts vs Zend? Java vs PHP?
- 29. Serializzazione Java vs JSON vs XML
- 30. javax vs pacchetto java
Penso che potresti avvicinarti usando il metodo del sondaggio su una coda di blocco. Ma hai ragione che l'istruzione select fornisce supporto sintattico per il multiplexing su un numero di canali diversi. –
Giusto, non ho parlato di busy-wait perché considero una non-soluzione :-). –