在Java中实现并发执行可以通过多种方式,最常见的方式包括使用线程、ExecutorService
、ForkJoinPool
等。以下是几种常用并发执行的示例:
1. 使用Thread
类
这是Java中最基础的并发实现,通过创建一个继承自Thread
的类或实现Runnable
接口来定义任务,并启动线程。
class MyTask extends Thread {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is executing task.");
}
}
public class Main {
public static void main(String[] args) {
MyTask task1 = new MyTask();
MyTask task2 = new MyTask();
task1.start();
task2.start();
}
}
2. 使用Runnable
接口
Runnable
接口更灵活,因为可以让任务类继承其他类,同时实现并发任务。
class MyRunnableTask implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is executing task.");
}
}
public class Main {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnableTask());
Thread thread2 = new Thread(new MyRunnableTask());
thread1.start();
thread2.start();
}
}
3. 使用ExecutorService
ExecutorService
是Java中用于管理线程池的接口,能够更高效地执行并发任务,适合管理大量并发任务。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Main {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
Runnable task1 = () -> {
System.out.println(Thread.currentThread().getName() + " is executing task 1.");
};
Runnable task2 = () -> {
System.out.println(Thread.currentThread().getName() + " is executing task 2.");
};
executor.submit(task1);
executor.submit(task2);
executor.shutdown(); // 关闭线程池
}
}
4. 使用Callable
和Future
Callable
接口允许任务返回结果,而Future
可以用于获取结果或控制任务的执行状态。
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
Callable<Integer> task = () -> {
System.out.println(Thread.currentThread().getName() + " is executing task.");
return 123;
};
Future<Integer> future = executor.submit(task);
// 阻塞等待结果
Integer result = future.get();
System.out.println("Task result: " + result);
executor.shutdown();
}
}
5. 使用ForkJoinPool
ForkJoinPool
是专门用于并行处理任务的线程池,特别适合用于递归任务。
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
class FibonacciTask extends RecursiveTask<Integer> {
private final int n;
public FibonacciTask(int n) {
this.n = n;
}
@Override
protected Integer compute() {
if (n <= 1) {
return n;
}
FibonacciTask f1 = new FibonacciTask(n - 1);
FibonacciTask f2 = new FibonacciTask(n - 2);
f1.fork();
return f2.compute() + f1.join();
}
}
public class Main {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
FibonacciTask task = new FibonacciTask(10);
Integer result = pool.invoke(task);
System.out.println("Fibonacci result: " + result);
}
}
这些例子展示了不同的Java并发编程方式,使用场景可以根据实际需求选择合适的实现方式。例如,对于简单的并发任务,Thread
和Runnable
就足够了;而对于复杂的任务,ExecutorService
或ForkJoinPool
可能会更高效。