一、简介
ExecutorService是Java中对线程池定义的一个接口,它java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法。
二、线程池
Java给我们提供了一个 Executors工厂类
,它可以帮助我们很方便的创建各种类型ExecutorService线程池,Executors一共可以创建下面这四类线程池:
- newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
- newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
- newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
- newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
三、代码举例
import org.junit.Test;
import java.util.concurrent.*;
/**
* @author :gongxr
* @description:ExecutorService是Java中对线程池定义的一个接口,它java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法。 Java通过Executors提供四种创建线程池的工厂类,分别为:
* newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
* newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
* newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
* newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
*/
public class TestExecutorService {
/**
* newCachedThreadPool:创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
*/
@Test
public void test1() throws InterruptedException {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始工作!");
Thread.sleep((long) (Math.random() * 3000));
System.out.println(Thread.currentThread().getName() + " 工作结束!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 5; i++) {
cachedThreadPool.execute(runnable);
}
Thread.sleep(3000);
System.out.println("主线程结束!");
cachedThreadPool.shutdown();
}
/**
* newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
*/
@Test
public void test2() throws InterruptedException {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始工作!");
Thread.sleep((long) (Math.random() * 3000));
System.out.println(Thread.currentThread().getName() + " 工作结束!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
for (int i = 0; i < 6; i++) {
final int index = i;
fixedThreadPool.execute(runnable);
}
Thread.sleep(6000);
fixedThreadPool.shutdown();
System.out.println("主线程结束!");
}
/**
* newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
* 该例中延迟3秒执行。
*/
@Test
public void test3_1() throws InterruptedException {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("delay 3 seconds");
}
};
scheduledThreadPool.schedule(runnable, 3, TimeUnit.SECONDS);
Thread.sleep(10000);
scheduledThreadPool.shutdown();
}
/**
* newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
* 延迟1秒后每3秒执行一次。
*/
@Test
public void test3_2() throws InterruptedException {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("delay 1 seconds, and excute every 3 seconds");
}
};
scheduledThreadPool.scheduleAtFixedRate(runnable, 1, 3, TimeUnit.SECONDS);
Thread.sleep(10000);
scheduledThreadPool.shutdown();
}
/**
* newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
*/
@Test
public void test4() throws InterruptedException {
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
Thread.sleep(10000);
singleThreadExecutor.shutdown();
}
/**
* submit(Callable)
* submit(Callable)和submit(Runnable)类似,也会返回一个Future对象,
* 但是除此之外,submit(Callable)接收的是一个Callable的实现,
* Callable接口中的call()方法有一个返回值,可以返回任务的执行结果,
* 而Runnable接口中的run()方法是void的,没有返回值。
*/
@Test
public void testCallable() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
Callable callable = new Callable() {
@Override
public Object call() throws InterruptedException {
String name = Thread.currentThread().getName();
System.out.println("Thread Name:" + name + " 开始工作!");
Thread.sleep((long) (Math.random() * 3000));
System.out.println("Thread Name:" + name + " 结束工作!");
return name;
}
};
Future future = executorService.submit(callable);
System.out.println("主线程继续执行!");
Thread.sleep(3000);
// future.get()使得主线程阻塞,等待子线程执行结束
System.out.println("子线程执行完回调结果:" + future.get().toString());
System.out.println("主线程结束!");
executorService.shutdown();
}
/**
* ExecutorService的shutdown、shutdownNow、awaitTermination用法:
* 调用shutdown方法之后,ExecutorService不再接收新的任务,直到当前所有线程执行完成才会关闭,所有之前提交的任务都会被执行。
* 调用shutdownNow方法后,将试图阻止所有正在执行的任务和被提交还没有执行的任务。
* awaitTermination方法的作用:监视各任务的状态是否已经结束,经过指定的时间后,全部完成返回true,反之返回false。
*/
@Test
public void testShutDown() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " 开始工作!");
Thread.sleep(2000);
System.out.println(Thread.currentThread().getName() + " 工作结束!");
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " 子线程中断!");
e.printStackTrace();
}
}
};
// 线程1
executorService.execute(runnable);
Thread.sleep(1000);
// 线程2
executorService.execute(runnable);
executorService.shutdown();
// 等待一秒后检查子线程运行状态,全部完成返回true
if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) {
System.out.println("主线程强制中断子线程!");
executorService.shutdownNow();
}
Thread.sleep(4000);
System.out.println("主线程结束!");
}
}
与多线程同步工具结合使用:
运行结果:
Original: https://www.cnblogs.com/gongxr/p/14463568.html
Author: 星瑞
Title: Java多线程之ExecutorService使用说明
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/538054/
转载文章受原作者版权保护。转载请注明原作者出处!