Principii de bază ale multi-threadingului

Optimizarea codului în Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Execuție secvențială vs. paralelă

  • Procesare secvențială -> operațiile se execută una după alta
  • Procesare paralelă -> mai multe operații se execută simultan

Cum?

  • Procesoarele moderne au mai multe nuclee
  • Thread: cea mai mică unitate de execuție a unui program
  • Multi-threadingul distribuie lucrul pe aceste nuclee

Execuția pe un singur thread e ca o șosea cu o singură bandă. Multi-threadingul e ca o șosea cu mai multe benzi, unde mașinile circulă simultan!

Optimizarea codului în Java

Utilizarea thread-urilor

  • Clasa Thread permite crearea de noi căi de execuție
  • Fiecare Thread se poate executa independent
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Optimizarea codului în Java

Lucrul cu mai multe thread-uri

List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < 4; i++) {
    Thread thread = new Thread(() -> System.out.println("Processing data on Thread-" + i));
    threads.add(thread);
    thread.start();
}

for (Thread t : threads) {
    t.join(); // Waits for all threads to complete
}
// Processing data on Thread-0
// Processing data on Thread-2
// Processing data on Thread-1
// Processing data on Thread-3
Optimizarea codului în Java

Stream-uri paralele

  • Stream-uri - funcționalitate Java 8+ pentru paralelism simplificat
  • Gestionează automat crearea și administrarea thread-urilor
  • Două moduri de creare:
    • collection.parallelStream()
    • Stream.of(...).parallel()
Optimizarea codului în Java

Exemplu de stream-uri paralele

// Sequential processing
List<Integer> result1 = new ArrayList<>();
for (int i = 0; i < numbers.size(); i++) {
    result1.add(numbers.get(i) * 2);
}

// Sequential processing with stream List<Integer> result2 = numbers.stream() .map(n -> n * 2) .collect(Collectors.toList());
// Parallel processing with parallel stream List<Integer> result3 = numbers.parallelStream() .map(n -> n * 2) .collect(Collectors.toList());
Optimizarea codului în Java

Când să utilizați procesarea paralelă

  • Operații intensive CPU
  • Procesare independentă a datelor
  • Colecții mari de date
  • Nuclee CPU disponibile > 1
  • Paralelizarea poate să nu merite pentru:
    • Seturi mici de date
    • Operații simple
Optimizarea codului în Java

Rezumat

  • Clasa Thread pentru crearea căilor de execuție paralelă
  • Stream-uri paralele pentru procesarea simplificată a colecțiilor
  • Beneficiile depind de:
    • Tipul sarcinii
    • Dimensiunea datelor
    • Nucleele disponibile
Optimizarea codului în Java

Să exersăm!

Optimizarea codului în Java

Preparing Video For Download...