博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java 线程池
阅读量:6423 次
发布时间:2019-06-23

本文共 3362 字,大约阅读时间需要 11 分钟。

  hot3.png

1.为什么要使用线程池?

在多线程的时候,如果不使用线程池而直接new Thread 或者实例化RunAble接口.在一些重复的请求时候,线程经常创建/结束.这样十分消耗资源,对速度也有影响.

使用线程池,相当于让线程池来管理线程的生命周期.也就是说,线程启动执行完之后,不再消亡二十处于空闲状态.再次有请求的时候,再启动该线程.并改变该线程的状态.这样,减少线程的反复创建.

 

 

2.线程池的使用

1. JDK中可以查到这些,而对于每个接口的说明,以及使用都有相应介绍.目前使用的最多的是ExecutorService与Executor接口.Executor与ExecutorService最大的区别在于后者可以启动有返回值的线程.更加丰富些.而ScheduledExecutorService是带延迟启动的线程池,一般用于定时任务.

2. Executor与ExecutorService,推荐使用后者.因为ExecutorService是对Executor的继承.所以对于没有返回值的线程,后者使用execute方法启动线程.与Executor的execute一样.

3. 线程池的新建方式常用的有ThreadPoolExecutor与Executors两个类.

141710_C5Rt_2934716.png1.Executors类创建线程池

1. newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
3. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
4. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

代码:

public class ThreadPool {	//多线程共用变量static int time = 0 ;		public static void main(String[] args) {		//创建线程池		ExecutorService  executor = Executors.newFixedThreadPool(10) ;				//创建线程		Runnable runnable = new Runnable() {						@Override			public void run() {				try {					Thread.sleep(100);					time++ ;					System.out.println("Start Thread:\t"+time);				} catch (InterruptedException e) {				}			}		};				//执行超过给定线程池的线程数目		for (int i = 0; i < 20; i++) {			executor.execute(runnable);		}				//主线程等待线程结束		while (((ThreadPoolExecutor) executor).getActiveCount() != 0) {			try {				Thread.sleep(500);			} catch (InterruptedException e) {				e.printStackTrace();			}		}		System.out.println("执行次数:\t" + time);		executor.shutdown();			}			}

输出结果:

Start Thread:	4Start Thread:	9Start Thread:	8Start Thread:	6Start Thread:	7Start Thread:	7Start Thread:	4Start Thread:	4Start Thread:	4Start Thread:	10Start Thread:	11Start Thread:	15Start Thread:	14Start Thread:	14Start Thread:	14Start Thread:	17Start Thread:	18Start Thread:	17Start Thread:	19Start Thread:	20执行次数:	20

这里没有1,是因为异步多线程的原因.

 

2.ThreadPoolExecutor类创建线程池.

public class ThreadPool {	//多线程共用变量static int time = 1 ;		public static void main(String[] args) {		//创建有边界的数组队列(FIFO)		BlockingQueue< Runnable> queue = new ArrayBlockingQueue
(10, true) ; //创建线程池,核心线程池大小为5,最大线程池为8.传入执行队列大小为10 ExecutorService executor = new ThreadPoolExecutor(5, 8, 10000, TimeUnit.HOURS, queue) ; //创建线程 Runnable runnable = new Runnable() { @Override public void run() { time ++ ; System.out.println("Thread Start:\t"+time); } }; //加入队列 for (int i = 0; i < 10; i++) { queue.add(runnable) ; } //执行队列里的线程 for (int i = 0; i < 20; i++) { if(queue != null && queue.peek() != null){ executor.submit(queue.poll()) ; } } //主线程等待线程结束 while (((ThreadPoolExecutor) executor).getActiveCount() != 0) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("执行次数:\t" + time); executor.shutdown(); } }

输出结果:

Thread Start:	3Thread Start:	5Thread Start:	6Thread Start:	3Thread Start:	4Thread Start:	7Thread Start:	8Thread Start:	11Thread Start:	10Thread Start:	9执行次数:	11

这里执行次数为11,是因为队列只有10个.

ps:这里可能会混淆,有一个core数量,max数量,队列数量.core与max是多线程里面的.队列的是队列里面的..感觉废话,不过不理解的话重复看一下.线程运行与队列无关,core数量是线程池最小数量,如果少于这个数量,线程池会自动创建新的线程加入线程池.如果线程池大于最大数量,则等待线程空闲.等待参数TimeUnit枚举类型.这里数量不要混淆了.

使用上来说,Executors获取线程池比较简单快速,但是性能上肯定不如new ThreadPollExecutor()处理线程.而且后者支持队列.关于队列,我后面文章有讲..

 

转载于:https://my.oschina.net/lmxy1990/blog/786302

你可能感兴趣的文章
HTML --块
查看>>
一个不错的loading效果
查看>>
Debian允许root用户登录
查看>>
linux的文件系统
查看>>
上云利器,K8S应用编排设计器之快到极致
查看>>
袋鼠云服务案例系列 | 从DB2到MySQL,某传统金融平台的互联网转型之路
查看>>
RealServer配置脚本
查看>>
九月份技术指标 华为交换机的简单配置
查看>>
python 写json格式字符串到文件
查看>>
分布式文件系统MogileFS
查看>>
Java23种设计模式案例:策略模式(strategy)
查看>>
XML解析之DOM4J
查看>>
图解微服务架构演进
查看>>
SQL PATINDEX 详解
查看>>
一些常用的网络命令
查看>>
CSP -- 运营商内容劫持(广告)的终结者
查看>>
DIV+CSS命名规范有助于SEO
查看>>
web项目buildPath与lib的区别
查看>>
我的友情链接
查看>>
ifconfig:command not found的解决方法
查看>>