Java并发——Executor框架(二)

总结看过的资料,方便自己学习。

来源: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线程结束 

猜你喜欢

转载自blog.csdn.net/zhm1563550235/article/details/84336432
今日推荐