# 线程池
Executors.newCachedThreadPool()
创建一个可缓存的线程池,线程池的初始大小是0,最大为2147483647。调用execute()加入的新任务会重用之前的线程(空闲的话),如果没有可用的线程会创建一个新的线程并加入到线程池中,空闲线程最大存活时间是60秒。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
}
ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 1000; i++) {
executorService.execute(() -> {
System.out.println("ThreadName: " + Thread.currentThread().getName());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
Executors.newFixedThreadPool(int nThreads)
创建一个固定大小的线程池,线程池的初始大小和最大值相同,超出的任务会放入队列中等待。
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
ExecutorService executorService = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
executorService.execute(() -> {
System.out.println("ThreadName: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
Executors.newScheduledThreadPool(int corePoolSize)
创建一个固定大小的线程池,线程池的初始大小和最大值相同,超出的任务会放入队列中等待,支持定时及周期性任务执行。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(3);
for (int i = 0; i < 10; i++) {
scheduledExecutorService.schedule(() -> {
System.out.println("ThreadName: " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 2, TimeUnit.SECONDS);
}
scheduledExecutorService.shutdown();
Executors.newSingleThreadExecutor()
创建一个大小为1的线程池,所有的任务会按照加入的顺序依次执行。
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>())
);
}
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
executorService.execute(() -> {
System.out.println("ThreadName: " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executorService.shutdown();
Executors.newSingleThreadScheduledExecutor()
创建一个大小为1的线程池,所有的任务会按照加入的顺序依次执行,支持定时及周期性任务执行。
public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
}
public ScheduledThreadPoolExecutor(int corePoolSize) {
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedWorkQueue());
}
ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
for (int i = 0; i < 10; i++) {
scheduledExecutorService.schedule(() -> {
System.out.println("ThreadName: " + Thread.currentThread().getName());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, 2, TimeUnit.SECONDS);
}
scheduledExecutorService.shutdown();
ExecutorService.shutdown()和ExecutorService.shutdownNow()
关闭线程池,shutdown()仅将线程池标记为SHUTWDOWN状态,而shutdownNow()会立刻停止执行任务并抛弃队列里尚未执行的任务,并将这些任务进行返回。
RUNNING
运行状态,执行队列里的任务且能接受新任务SHUTDOWN
指调用了shutdown()
方法,不再接受新任务了,但是队列里的任务继续执行完毕STOP
指调用了shutdownNow()
方法,不再接受新任务,同时抛弃阻塞队列里的所有任务并中断所有正在执行任务TIDYING
所有任务都执行完毕,在调用shutdown()/shutdownNow()
中都会尝试更新为这个状态TERMINATED
终止状态,当执行terminated()
后会更新为这个状态
调用shutdownNow()后,如果此时有任务正在执行,会进行一次中断操作,此时对应的线程报InterruptedException异常。
public List<Runnable> shutdownNow() {
List<Runnable> tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
checkShutdownAccess();
advanceRunState(STOP);
interruptWorkers();
tasks = drainQueue();
} finally {
mainLock.unlock();
}
tryTerminate();
return tasks;
}
ExecutorService.awaitTermination(long timeout, TimeUnit unit)
查看线程池状态,这个方法接收两个参数,超时时间和时间单位。它会阻塞并在超时后检测线程池是否关闭,关闭返回true否则返回false,如果在超时之前线程池提前关闭会立刻返回true。该方法仅检测线程池状态不会关闭线程池,通常和shutdown()一起使用。
executorService.shutdown();
while (!executorService.awaitTermination(10, TimeUnit.SECONDS)) {
System.out.println("Thread Running ...");
}
System.out.println("Thread Terminated");
ThreadPoolExecutor.execute(Runnable command)
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}