2009-03-02 9 views
16

Sembra esserci molta confusione su multicore e java. Mentre alcune persone dicono che il supporto java non è good enough, sembra decisamente un'area in cui guardare avanti. Sembra che ci sia manytechniques per migliorare le prestazioni dei programmi concorrenti.Suggerimenti per la codifica di programmi java in uno scenario multicore

Sono graditi suggerimenti/consigli sulla programmazione in uno scenario multi-core.

+0

Chi pensa che questa domanda non sia costruttiva? È costruttivo. – Xofo

risposta

21

Esaminare le nuove funzionalità di concorrenza Java (nello java.util.concurrent package) che sono state aggiunte in Java 5. Fornisce funzionalità di livello più elevato rispetto al normale Thread s che renderà più semplice (e meno soggetto a errori) a scrivere applicazioni concorrenti. Il Lesson: Concurrency di The Java Tutorials sarebbe un buon punto di partenza.

Finora, ho usato solo la ExecutorService, che permette in grado di produrre thread pools, a cui nuovi compiti possono essere consegnati in unità di Runnable s o Callable s (cosa che può riportare i valori dopo l'esecuzione come Future s), e l'attuale codice di threading è gestito dallo ExecutorService.

Ad esempio, eseguendo un calcolo utilizzando un pool di thread di 2 fili, e ottenendo 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 precedente (non testato), tutto devo preoccuparsi è fare un paio di Callable se submit e portarlo allo ExecutorService e in seguito, usando lo Future s per recuperare il risultato.

Il problema è che, una volta chiamato il metodo get di Future, se l'elaborazione non è completa, il programma si interromperà fino a quando il risultato dello Future può essere recuperato. Pertanto, in questo esempio, anche se il risultato di f2 è disponibile prima dello f1, il programma attenderà fino a quando il risultato di f1 non sarà disponibile.

In termini di materiale di lettura, sul mio elenco di libri per l'acquisto a breve è Java Concurrency in Practice di Brian Goetz, che si presenta spesso quando viene presentata la concorrenza in Java.

La pagina Concurrency Utilities dalla documentazione di Java 5 ha anche ulteriori informazioni.

6

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

+0

+1. Ho sempre progettato le classi come immutabili e rendendole mutevoli solo se necessario. – Fortyrunner

8

Il miglior consiglio deve essere: ottenere la sincronizzazione corretta!

Questo può sembrare un po 'ovvio, ma la comprensione della Java Memory Model è vitale, in particolare come volatili e finali campi funziona, come sincronizzati agisce sia come mutex e una barriera memoria e poi i nuovi costrutti java.util.concurrent

2

Dai un'occhiata ai talk di Brian Goetz From concurrent to Parallel di Devoxx 2008. Non ci sono molti suggerimenti, ma ti dà un'idea della direzione della concorrenza Java.

1

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

3

Controllare il prossimo fork-join framework. Il framework fork-join consente agli sviluppatori di ottenere un parallelismo a grana fine su architetture multicore.

Inoltre, è possibile verificare i linguaggi basati su JVM come Clojure che pretendono di rendere più semplice la programmazione parallela multicore.

3

In alternativa all'approccio della memoria condivisa di Java alla concorrenza, è possibile anche esaminare Actor-based concurrency using Scala su Java, che fornisce un modello più semplice per la programmazione simultanea.

1

Il mio consiglio: Comprendere il modello di memoria Java (dal JDK 5 in poi). La maggior parte delle persone non sa che sincronizzazione, volatilità e finale hanno un significato aggiuntivo oltre il normale ambito di multi-threading.

Java va bene per multi-CPU e multi-core. Se si programma correttamente e si investe un po 'di cervello, si ottiene un sistema server altamente concorrente per utilizzare 8 core, tra cui un sacco di sincronizzazione e così via. Ne siamo abbastanza contenti ... JDK6 è migliore di JDK5 e tutto ciò che segue fa schifo su macchine multi-cpu.

2

È possibile provare a utilizzare una libreria di modelli di parallelismo come Skandium per Java. Basta scegliere il modello di parallelismo che si desidera e compilare i ganci mancanti.

Alcuni dei modelli sopported 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);
  • ramificazione condizionale: If<P,R>(condition, trueCase, falseCase);
  • Map-ridurre: Map<P,R>(split, nested, merge);
  • Map-ridurre con percorsi di codice differenti: Fork<P,R>(split, nested, merge);
  • divide ricorsivo e conquista: DaC<P,R>(condition, split, nested, merge);

Tutti i modelli può essere annidato e combinato, in modo da poter avere fattoria all'interno di un dividere e conquistare, ecc.