Java multithreading is a fundamental feature that allows multiple threads to execute concurrently within a single Java program. A thread is an independent path of execution within a process. By creating and managing multiple threads, a Java application can perform multiple tasks simultaneously, taking advantage of multi - core processors to improve performance. Java provides several ways to create and manage threads, such as extending the Thread
class or implementing the Runnable
interface.
Parallel streams are a feature introduced in Java 8 as part of the Stream API. A stream is a sequence of elements supporting various operations, such as filtering, mapping, and reducing. Parallel streams allow these operations to be executed in parallel across multiple threads, leveraging the underlying Fork - Join framework to split the work among multiple threads automatically. This can significantly speed up the processing of large collections.
class MyRunnable implements Runnable {
private final int id;
public MyRunnable(int id) {
this.id = id;
}
@Override
public void run() {
System.out.println("Thread " + id + " is running.");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread " + id + " is finished.");
}
}
public class MultiThreadingExample {
public static void main(String[] args) {
Thread[] threads = new Thread[5];
for (int i = 0; i < 5; i++) {
threads[i] = new Thread(new MyRunnable(i));
threads[i].start();
}
for (Thread thread : threads) {
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("All threads are finished.");
}
}
In this example, we define a Runnable
implementation MyRunnable
and create five threads to execute it. We use the start()
method to start each thread and the join()
method to wait for all threads to finish.
import java.util.Arrays;
import java.util.List;
public class ParallelStreamsExample {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.parallelStream()
.mapToInt(Integer::intValue)
.sum();
System.out.println("The sum of the numbers is: " + sum);
}
}
In this example, we create a list of integers and use the parallelStream()
method to create a parallel stream. Then we perform a mapping operation and calculate the sum of the elements in parallel.
ExecutorService
interface in Java provides a convenient way to manage a pool of threads. For example:import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
class MyTask implements Runnable {
@Override
public void run() {
System.out.println("Task is running.");
}
}
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(5);
for (int i = 0; i < 10; i++) {
executor.submit(new MyTask());
}
executor.shutdown();
}
}
synchronized
blocks or Lock
interfaces to prevent race conditions.java.util.concurrent.ForkJoinPool.common.parallelism
system property.Both Java multithreading and parallel streams are powerful tools for achieving concurrency in Java. Java multithreading is more suitable for complex scenarios where fine - grained control over threads is required, such as implementing custom thread pools and handling complex synchronization requirements. Parallel streams, on the other hand, are a great choice for simple data processing tasks on large data sets, as they provide an easy - to - use and efficient way to parallelize operations. When choosing between them, consider the complexity of your task, the size of your data set, and the performance requirements of your application.