目录
- 在Java中,线程池是一种管理并复用线程的机制,它可以提高应用程序的性能和资源利用率。Java提供了多种方式来创建和使用线程池。
- 下面是一些常见的线程池类型以及它们的实现示例:
一、FixedThreadPool
- 固定大小的线程池,一旦创建就拥有固定数量的线程。
// 代码如下
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FixedThreadPoolExample {
public static void main(String[] args) {
// 创建一个具有固定数量(3个)的线程池
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
// 关闭线程池
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
二、CachedThreadPool
- 根据需要创建新线程的线程池,如果线程有空闲时间超过60秒,则将其移除。
// 代码如下
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CachedThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
三、ScheduledThreadPool
- 可以用于计划执行定时任务的线程池。
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledThreadPoolExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
Runnable task1 = () -> System.out.println("Executing Task1 at " + System.nanoTime());
Runnable task2 = () -> System.out.println("Executing Task2 at " + System.nanoTime());
// 任务将在5秒后执行
executor.schedule(task1, 5, TimeUnit.SECONDS);
// 任务将在2秒后初次执行,并每5秒执行一次
executor.scheduleAtFixedRate(task2, 2, 5, TimeUnit.SECONDS);
// 停止调度器,但会等待现有任务完成
executor.shutdown();
}
}
四、SingleThreadExecutor
- 单线程的线程池,确保所有任务按照顺序执行。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SingleThreadExecutorExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
while (!executor.isTerminated()) {
}
System.out.println("Finished all threads");
}
}
class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
五、WorkStealingPool
- 工作窃取线程池,是Java 8新增的一种线程池类型。它使用一种称为"工作窃取"的算法,允许空闲线程从其他线程的任务队列中窃取任务来执行,以实现更高效的任务调度。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class WorkStealingPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newWorkStealingPool();
for (int i = 0; i < 10; i++) {
Runnable worker = new WorkerThread("" + i);
executor.execute(worker);
}
executor.shutdown();
try {
executor.awaitTermination(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished all threads");
}
}
class WorkerThread implements Runnable {
private String command;
public WorkerThread(String s) {
this.command = s;
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " Start. Command = " + command);
processCommand();
System.out.println(Thread.currentThread().getName() + " End.");
}
private void processCommand() {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@Override
public String toString() {
return this.command;
}
}
六、ForkJoinPool
- 分治任务线程池,也是Java 8新增的一种线程池类型。它是基于分治算法的思想,在处理大规模任务时具有较好的性能表现。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
public class ForkJoinPoolExample {
public static void main(String[] args) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
MyRecursiveAction action = new MyRecursiveAction(24);
forkJoinPool.invoke(action);
}
}
class MyRecursiveAction extends RecursiveAction {
private int workload;
public MyRecursiveAction(int workload) {
this.workload = workload;
}
@Override
protected void compute() {
if (workload > 16) {
System.out.println("Splitting workload: " + workload);
MyRecursiveAction subtask1 = new MyRecursiveAction(workload / 2);
MyRecursiveAction subtask2 = new MyRecursiveAction(workload / 2);
invokeAll(subtask1, subtask2);
} else {
System.out.println("Doing workload myself: " + workload);
}
}
}
七、CompletableFuture
- CompletableFuture是Java 8引入的一个类,它提供了一种方便的方式来进行异步编程。CompletableFuture可以用于执行异步任务,并在任务完成后执行回调操作。
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenApply(String::toUpperCase);
future.thenAccept(System.out::println);
}
}
-
总结起来,Java中的线程池概念非常丰富,可以根据具体的需求选择合适的线程池类型和相关的实现机制。这些线程池可以提高应用程序的并发性能、资源利用率和代码可维护性。