总结看过的资料,方便自己学习。
来源:https://blog.csdn.net/zxm490484080/article/details/80886243
前面学习了Executor框架的组成,Executor和ExecutorService的区别,以及ExecutorService常用方法的使用
接下来学习Executors类.
1. Executors类
是java.util.concurrent包下的一个类,提供了若干个静态方法,用于生成不同类型的线程池。Executors一共可以创建下面这四类线程池:
(1)newCachedThreadPool:创建一个可按需自动扩容的线程池,但是会优先重用线程池中空闲可用的线程。如果线程池中线程都在使用,又有新任务到来,则新增一个线程到线程池。如果线程 60 秒内空闲,则将被终止移除线程池。(线程最大并发数不可控制)
(2)newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
(3)newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
(4)newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(5)newWorkStealingPool:jdk1.8新增,创建持有足够线程的线程池来支持给定的并行级别,并通过使用多个队列,减少竞争,它需要穿一个并行级别的参数,如果不传,则被设定为默认的CPU数量。
2. 利用Executors类的四种方法创建线程池
首先创建一个实现了Runnable接口的类,用于提供线程的执行代码
//利用Executors类的四种方法创建线程池
public class ThreadPoolUtil implements Runnable{
private Integer index;
public ThreadPoolUtil(Integer index)
{
this.index = index;
}
@Override
public void run()
{
try {
System.out.println(index+"开始处理线程");
Thread.sleep(50);
System.out.println("线程标识是"+ this.toString());
System.out.println(index+"线程结束");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
(1)newCachedThreadPool方法
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
//利用Executors类的四种方法创建线程池
//这里利用newCachedThreadPool函数
public class ThreadPools_newCachedThreadPool {
public static void main(String[] args)
{
ExecutorService executorService = Executors.newCachedThreadPool();
System.out.println("---------------newCachedThreadPool--------------");
for(int i = 0; i < 4; i++)
{
final int index = i;
executorService.execute(new ThreadPoolUtil(index));
}
}
}
运行结果:可知四个线程是并行处理。
---------------newCachedThreadPool--------------
2开始处理线程
0开始处理线程
1开始处理线程
3开始处理线程
线程标识是ThreadPoolUtil@1d93e3d8
0线程结束
线程标识是ThreadPoolUtil@4b8e7f5c
2线程结束
线程标识是ThreadPoolUtil@6a5235dc
1线程结束
线程标识是ThreadPoolUtil@5da2b6d5
3线程结束
(2)newFixedThreadPool方法
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPools_newFixedTreadPool {
public static void main(String[] args)
{
//创建一个固定为2的定长线程池
ExecutorService executorService = Executors.newFixedThreadPool(2);
System.out.println("---------------newFixedThreadPool--------------");
for(int i = 0; i < 4; i++)
{
final int index = i;
executorService.execute(new ThreadPoolUtil(index));
}
}
}
运行结果:同样是四个线程,但是这时设置了线程固定大小是2,所以两个线程先新建,运行完毕后剩下的再执行。
---------------newFixedThreadPool--------------
1开始处理线程
0开始处理线程
线程标识是ThreadPoolUtil@521caf8a
线程标识是ThreadPoolUtil@3ffe3b3a
1线程结束
2开始处理线程
0线程结束
3开始处理线程
线程标识是ThreadPoolUtil@3139c2b5
2线程结束
线程标识是ThreadPoolUtil@5cdb4bb9
3线程结束
(3)newScheduledThreadPool
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPools_newScheduledThreadPool {
public static void main(String[] args)
{
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
System.out.println("---------------newScheduledThreadPool--------------");
for(int i = 0; i<4;i++)
{
final int index = i;
executorService.schedule(new ThreadPoolUtil(index), 3, TimeUnit.SECONDS);
}
}
}
运行结果:除了延迟3秒执行,别的和newFixedThreadPool相同
---------------newScheduledThreadPool--------------
1开始处理线程
0开始处理线程
线程标识是ThreadPoolUtil@5c8e5d81
线程标识是ThreadPoolUtil@7163d92a
1线程结束
0线程结束
2开始处理线程
3开始处理线程
线程标识是ThreadPoolUtil@3a86097
3线程结束
线程标识是ThreadPoolUtil@34614962
2线程结束
(4)newSingleThreadExecutor 方法
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPools_newSingleThreadExecutor {
public static void main(String[] args)
{
ExecutorService executorService = Executors.newSingleThreadExecutor();
System.out.println("---------------newSingleThreadExecutor--------------");
for(int i = 0; i < 4; i++)
{
final int index = i;
executorService.execute(new ThreadPoolUtil(index));
}
}
}
运行结果:每次只执行一个线程,并且是按顺序执行。
---------------newSingleThreadExecutor--------------
0开始处理线程
线程标识是ThreadPoolUtil@3ffe3b3a
0线程结束
1开始处理线程
线程标识是ThreadPoolUtil@3139c2b5
1线程结束
2开始处理线程
线程标识是ThreadPoolUtil@3506504a
2线程结束
3开始处理线程
线程标识是ThreadPoolUtil@7004c88e
3线程结束