Domanda

Sembra che ci sia molta confusione su multicore e java. Mentre alcune persone dicono che il supporto java non è abbastanza buono , sembra sicuramente essere un'area da guardare al futuro. Sembra che ci siano molti tecniche per migliorare le prestazioni dei programmi simultanei.

Sono apprezzati tutti i suggerimenti / consigli sulla programmazione in uno scenario multi core.

È stato utile?

Soluzione

Cerca nelle nuove funzionalità di concorrenza Java (nella java.util.concurrent pacchetto ) che sono stati aggiunti in Java 5. Offre funzionalità che sono più di alto livello rispetto ai normali Thread s che lo renderanno più facile (e meno soggetto a errori) per scrivere applicazioni simultanee. La Lezione: concorrenza di I tutorial Java sarebbe un buon punto di partenza.

Finora ho usato solo ExecutorService , che consente di produrre thread pool , a cui possono essere consegnati nuovi compiti in unità di Runnable s oppure Callable s (che può restituire valori dopo l'esecuzione come Future s) e il codice di threading effettivo viene gestito da submit.

Ad esempio, eseguire alcuni calcoli utilizzando un pool di thread di 2 thread e ottenere il risultato può essere semplice come:

ExecutorService es = Executors.newFixedThreadPool(2);

Future f1 = es.submit(new Callable<Integer>() {
    public Integer call()
    {
        // Do some processing...
        return someInteger;
    }
});

Future f2 = es.submit(new Callable<Integer>() {
    public Integer call()
    {
        // Do some processing...
        return someInteger;
    }
});

Integer firstInteger = f1.get();
Integer secondInteger = f2.get();

Nel codice sopra (non testato), tutto ciò di cui devo preoccuparmi è fare un paio di get se f2 inserendolo nel f1 e successivamente, usando < => s per recuperare il risultato.

Il problema è che, una volta <=> del <=>, se l'elaborazione non è completa, il programma si arresterà fino a quando non sarà possibile recuperare il risultato di <=>. Pertanto, in questo esempio, anche se il risultato di <=> è disponibile prima di <=>, il programma attenderà fino a quando non sarà disponibile il risultato di <=>.

In termini di materiale di lettura, il mio elenco di libri da acquistare a breve è Java Concurrency in Practice di Brian Goetz, che si presenta spesso quando viene avviata la concorrenza in Java.

La Utilità di concorrenza dalla documentazione Java 5 ha anche maggiori informazioni.

Altri suggerimenti

Il miglior consiglio deve essere: ottieni la sincronizzazione corretta!

Questo può sembrare in qualche modo ovvio, ma una comprensione del Java Memory Model è di vitale importanza, in particolare come funzionano i campi volatili e finali , come sincronizzato funge sia da mutex che una barriera di memoria e quindi anche i nuovi java.util.concurrent costrutti

Sempre un buon consiglio: se la maggior parte delle lezioni è immutabile, tutto diventa molto più semplice poiché l'immutabilità elimina la necessità di preoccuparsi di blocchi da molti a pochi punti di preoccupazione.

Dai un'occhiata all'imminente fork-join framework . Il framework fork-join consente agli sviluppatori di ottenere un parallelismo approfondito sulle architetture multicore.

Inoltre potresti voler controllare lingue basate su JVM come Clojure che affermano di rendere più semplice la programmazione parallela multicore.

In alternativa all'approccio alla concorrenza della memoria condivisa di Java, puoi anche esaminare Concorrenza basata sugli attori che utilizza Scala su Java, che fornisce un modello più semplice per la programmazione concorrente.

Dai un'occhiata al discorso di Brian Goetz Da concorrente a parallelo di Devoxx 2008. Non ci sono molti consigli, ma ti dà un'idea di dove si stia dirigendo la concorrenza Java.

Puoi provare a utilizzare una libreria di schemi di parallelismo come Skandium per Java. Basta scegliere il modello di parallelismo desiderato e compilare i ganci mancanti.

Alcuni dei modelli sostenuti in Skandium sono:

  • Master-slave: Farm<P,R>(nested);
  • Pipeline: `Pipe (stage1, stage2);
  • Per iterazione: For<P,R>(nested, i);
  • Iterazione condizionale: While<P,R>(nested, condition);
  • Diramazione condizionale: If<P,R>(condition, trueCase, falseCase);
  • Riduzione mappa: Map<P,R>(split, nested, merge);
  • Riduci mappa con percorsi di codice diversi: Fork<P,R>(split, nested, merge);
  • Divisione ricorsiva e conquista: DaC<P,R>(condition, split, nested, merge);

Tutti i motivi possono essere nidificati e combinati, quindi puoi avere una fattoria all'interno di una divisione e conquista, ecc.

Il miglior libro con consigli pratici è stato Java Concurrency in Practice . È una lettura obbligatoria per tutti i programmatori Java, anche per quelli che pensano di non fare alcuna programmazione concorrente, perché Java ha molti thread nascosti nelle sue varie librerie (viene in mente lo swing, lo stesso con i servlet).

Il mio consiglio: comprendi il modello di memoria Java (dal JDK 5 in poi). Molte persone non sanno che la sincronizzazione, la volatilità e il finale hanno un significato aggiuntivo oltre il normale ambito multi-threading.

Java va bene per multi-cpu e multi-core. Se lo programmate nel modo giusto e investite un po 'di cervello, otterrete un sistema server altamente simultaneo che utilizza 8 core, inclusa molta sincronizzazione e così via. Ne siamo abbastanza contenti ... JDK6 è meglio di JDK5 e tutto ciò che segue fa schifo su macchine multi-CPU.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top