Basic multi-threading principles

Optimizing Code in Java

Pavlos Kosmetatos

Lead Engineer @Wealthyhood

Sequential vs parallel execution

  • Sequential processing -> operations happen one after another
  • Parallel processing -> multiple operations happen simultaneously

How?

  • Modern CPUs have multiple cores
  • Thread: the smallest unit of program execution
  • Multi-threading distributes work across these cores

Single-threading is like having a single-lane road where cars must follow one another. Multi-threading is like having multiple lanes where cars can travel simultaneously!

Optimizing Code in Java

Using threads

  • Thread class allows creating new execution paths
  • Each Thread can execute independently
Runnable task = () -> {
    System.out.println("Processing on thread: " + 
                       Thread.currentThread().getName());
};

Thread thread = new Thread(task);
thread.start();
Processing on thread: Thread-0
Optimizing Code in Java

Working with multiple threads

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
Optimizing Code in Java

Parallel streams

  • Streams - Java 8+ feature for simplified parallelism
  • Automatically handles thread creation and management
  • Two ways to create:
    • collection.parallelStream()
    • Stream.of(...).parallel()
Optimizing Code in Java

Parallel streams example

// 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());
Optimizing Code in Java

When to use parallel processing

  • CPU-intensive operations
  • Independent data processing
  • Large data collections
  • Available CPU cores > 1
  • Parallelization overhead may not be worth it for:
    • Small data sets
    • Simple operations
Optimizing Code in Java

Summary

  • Thread class for creating parallel execution paths
  • Parallel streams for simplified collection processing
  • Benefits depend on:
    • Workload type
    • Data size
    • Available cores
Optimizing Code in Java

Let's practice!

Optimizing Code in Java

Preparing Video For Download...