【多线程】五种线程池简介


针对不同的情况,我们可以根据不同线程池的特性来实现不同的业务。那线程池总共分为哪几种呢?

(1)、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
(2)、newFixedThreadPool创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

(3)、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(4)、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

(5)、newWorkStealingPool创建持有足够的线程的线程池来支持给定的并行级别,该方法还有使用多个队列来减少竞争。

newCachedThreadPool:

public static void main(String[] args) {  
	 ExecutorService cachedThreadPool = Executors.newCachedThreadPool();  
	 for (int i = 0; i < 10; i++) {  
		 final int index = i;  
		 try { 
			 System.out.println("put index="+index+"***"+new Date().getSeconds());
			 Thread.sleep(3000);  
		 } catch (InterruptedException e) {  
			 e.printStackTrace();  
		 } 
		 cachedThreadPool.execute(new Runnable() {  
			 public void run() {
				 try {  
					 Thread.sleep(index * 1000);  
				 } catch (InterruptedException e) {  
					 e.printStackTrace();  
				 }  
				 System.out.println(Thread.currentThread().getName()+"***"+new Date().getSeconds()+"========"+index);  
		     }  
	     });  
	}  
}


       从上图中,我们可以看到,此线程池的容量是可以自动无限扩大的,但是很明显,他也不会无缘无故的养活那么多闲人,当任务执行完成后,会复用已经存在的线程执行新的任务,不会每次都新建线程。



newFixedThreadPool 
public static void main(String[] args) {
	ExecutorService fixedThreadPool=Executors.newFixedThreadPool(3);
	for (int i = 0; i < 10; i++) {
		final int index=i;
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println(Thread.currentThread().getName()+"***"+new Date().getSeconds()+"====="+index);
					Thread.sleep(2000);
				} catch (Exception e) {
					e.printStackTrace(); 
				}
			}
		});
	}
}

        大家从此线程池的构造方法上应该也能看出来,他是可以创建定长线程池的,然后从图中可以看出,每次最多执行3个线程。

注意:定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()

newSingleThreadExecutor 

public static void main(String[] args) {
	ExecutorService singleThreadPool=Executors.newSingleThreadExecutor();
	for (int i = 0; i < 10; i++) {
		final int index=i;
		singleThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				try {
					System.out.println(Thread.currentThread().getName()+"***"+new Date().getSeconds()+"====="+index);
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
}


这个就没有什么好解释的了吧!


newScheduledThreadPool 
public static void main(String[] args) {
	ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(3);
	System.out.println(new Date().getSeconds());
	scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
		@Override
		public void run() {
			System.out.println(Thread.currentThread().getName()+"***"+new Date().getSeconds()+"===== I love LSR");
		}
	},3,TimeUnit.SECONDS);
}


图中我们可以看出来,初时是39秒点,执行任务是42秒点,正好延时3秒执行。


public static void main(String[] args) {
	ScheduledExecutorService scheduledThreadPool=Executors.newScheduledThreadPool(3);
	System.out.println(new Date().getSeconds());
	scheduledThreadPool.schedule(new Runnable() {
		@Override
		public void run() {
			System.out.println(Thread.currentThread().getName()+"***"+new Date().getSeconds()+"===== I love LSR");
		}
	},0,3,TimeUnit.SECONDS);
}


这里不仅延时0秒点(设计失误,最好是能看出延时效果来),而且每3秒执行一次,也就是也用来执行定时和周期性任务。那我们能不能指定时间点去执行,而不是计算延时呢?答案是否定的!


评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值