English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Flusso parallelo e flusso sequenziale
Il flusso parallelo è un flusso che divide un contenuto in più blocchi di dati e tratta ciascun blocco di dati con un thread diverso.
In Java 8, la parallelizzazione è stata ottimizzata, possiamo facilmente eseguire operazioni parallele sui dati. L'API Stream può passare dichiarativamente tra flussi paralleli e sequenziali utilizzando parallel() e sequential().
Comprendere il framework Fork/Join
Il framework Fork/Join: è necessario dividere un grande compito in più piccoli compiti (fissare in modo che non possa essere diviso ulteriormente), quindi unire i risultati dei singoli piccoli compiti in un unico risultato.
La differenza tra il framework Fork/Join e il pool di thread tradizionale:
Utilizza lo schema di 'stolen work':
Quando si esegue un nuovo compito, può dividerlo in compiti più piccoli per eseguire, aggiungere i piccoli compiti alla coda dei thread e poi rubare uno da una coda casuale di un thread e metterlo nella propria coda.
L'advantage del framework fork/join rispetto all'implementazione tradizionale di pool di thread si manifesta nel modo in cui gestisce i compiti inclusi. In un pool di thread tradizionale, se un thread non può continuare a eseguire un compito per qualche motivo, il thread rimane in stato di attesa. Nel framework implementativo di fork/join, se una sottoproblema non può continuare a eseguire a causa dell'attesa della completazione di un altro sottoproblema, il thread che gestisce il sottoproblema cerca attivamente altri sottoproblemi non eseguiti da eseguire. Questo metodo riduce il tempo di attesa dei thread, migliorando le prestazioni.
import java.time.Duration; import java.time.Instant; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinTask; import java.util.concurrent.RecursiveTask; import java.util.stream.LongStream; public class TestForkJoin { public static void main(String[] xx){ } private static void test1(){} Instant start=Instant.now(); ForkJoinPool pool=new ForkJoinPool(); ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L); long sum = pool.invoke(task); System.out.println(sum); Instant end=Instant.now(); System.out.println("Tempo di esecuzione"+Duration.between(start, end).toMillis()+"ms");//Tempo di esecuzione 3409ms } private static void test2(){ Instant start=Instant.now(); Long sum = LongStream.rangeClosed(0L, 10000L); .parallel(); .reduce(0,Long::sum); System.out.println(sum); Instant end=Instant.now(); System.out.println("Tempo di esecuzione" + Duration.between(start, end).toMillis()+"ms");//Tempo di esecuzione 2418ms } } class ForkJoinCalculate extends RecursiveTask<Long>{ private static final long serialVersionUID = 1234567890L;//序列号 private long start; private long end; private static final long THRESHOLD=2500000000L;//临界值 public ForkJoinCalculate(long start,long end) { this.start=start; this.end=end; } @Override protected Long compute() { long length = end - start; if(length <= THRESHOLD){ long sum=0; for(long i = start; i <= end; i++){ sum += i; } return sum; }else{ long middle = (start+end)/2; ForkJoinCalculate left = new ForkJoinCalculate(start, middle); left.fork(); ForkJoinCalculate right=new ForkJoinCalculate(middle+1, end); right.fork(); return left.join() + right.join(); } } }
Classe Optional
La classe Optional< T>(java.util.Optional) è una classe contenitore che rappresenta l'esistenza o l'assenza di un valore.
Prima si usava null per rappresentare l'assenza di un valore, ora Optional può esprimere meglio questo concetto e può evitare l'eccezione di puntatore nullo.
Metodi comuni:
Optional.of(T t) : Crea un'istanza di Optional
Optional.empty() : Crea un'istanza di Optional vuota
Optional.ofNullable(T t):Se t non è null, crea un'istanza di Optional, altrimenti crea un'istanza vuota
isPresent() : Determina se contiene un valore
orElse(T t) : Se l'oggetto chiamato contiene un valore, restituisce quel valore, altrimenti restituisce t
orElseGet(Supplier s) : Se l'oggetto chiamato contiene un valore, restituisce quel valore, altrimenti restituisce il valore ottenuto da s
map(Function f): Se esiste un valore, lo elabora e restituisce l'Optional elaborato, altrimenti restituisce Optional.empty()
flatMap(Function mapper):Simile a map, richiede che il valore di ritorno sia Optional
public class OptionalTest1 { public static void main(String[] args){ String s = new String("Ha"); // Optional<String> op = Optional.of(null); // // String s1 = op.get(); // System.out.println(s1); // Optional<String> op1 = Optional.empty(); // String s1 = op1.get(); // System.out.println(s1); Optional<String> op1 = Optional.ofNullable(null); // System.out.println(op1.isPresent()); // System.out.println(op1.orElse(new String("Google"))); //System.out.println(op1.orElseGet(() -> new String("Ali"))); Optional<String> op2 = op1.map((x) -> x.toLowerCase()); String s2 = op2.get(); System.out.println(s2); } }
@Test public void test5(){ Man man=new Man(); String name=getGodnessName(man); System.out.println(name); } //Richiesta: ottenere il nome della dea nel cuore di un uomo public String getGodnessName(Man man){ if(man!=null){ Godness g=man.getGod(); if(g!=null){ return g.getName(); } } return "maestro Cang"; } //Applicazione della classe entity di Optional @Test public void test6(){ Optional<Godness> godness=Optional.ofNullable(new Godness("Ling Zhi")); Optional<NewMan> op=Optional.ofNullable(new NewMan(godness)); String name=getGodnessName2(op); System.out.println(name); } public String getGodnessName2(Optional<NewMan> man){ return man.orElse(new NewMan()) .getGodness() .orElse(new Godness("maestro Cang")) .getName(); } //Attenzione: Optional non può essere serializzato public class NewMan { private Optional<Godness> godness = Optional.empty(); private Godness god; public Optional<Godness> getGod(){ return Optional.of(god); } public NewMan() { } public NewMan(Optional<Godness> godness) { this.godness = godness; } public Optional<Godness> getGodness() { return godness; } public void setGodness(Optional<Godness> godness) { this.godness = godness; } @Override public String toString() { return "NewMan [godness=" + godness + "]"; } }
Ecco tutto il contenuto che abbiamo raccolto sui sentimenti di utilizzo dei framework forkjoin e optional in Java 8, se hai qualsiasi dubbio durante lo studio, puoi discuterlo nella sezione dei commenti sottostante.
Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, il copyright è di proprietà del rispettivo proprietario, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume alcuna responsabilità legale correlata. Se trovi contenuti sospetti di copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare il problema e fornire prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente il contenuto sospetto di copyright.