多线程学习(2):ScheduledThreadPoolExecutor 与 schedule 之小结

2018年7月9日08:48:58

欢迎扫二维码关注公众号,获取技术干货

【1】前言

    线程池与任务定时执行,一是项目随处可见的一种技术,二是自己还需打打扎实基础;不可以仅仅局限于业务的实现,要去体会底层的思想;

 

【2】关于线程池ThreadPoor与Timer的使用

 

2.1    Java提供的Time类可以周期性地或者延期执行任务,但是有时我们需要并行执行同样的任务,这个时候如果创建多个Time对象会给系统带来负担,解决办法是将定时任务放到线程池中执行。

    Java的ScheduledThreadPoolExecutor类实现了ScheduledExecutorService接口中定义的以不同方法执行任务的方法。

2.2 ScheduleThreadPoolExecutor与Timer相比的优势

 

(1)Timer是基于绝对时间的延时执行或周期执行,当系统时间改变,则任务的执行会受到的影响。而ScheduleThreadPoolExecutore中,任务时基于相对时间进行周期或延时操作。

(2)Timer也可以提交多个TimeTask任务,但只有一个线程来执行所有的TimeTask,这样并发性受到影响。而ScheduleThreadPoolExecutore可以设定池中线程的数量。

(3)Timer不会捕获TimerTask的异常,只是简单地停止,这样势必会影响其他TimeTask的执行。而ScheduleThreadPoolExecutore中,如果一个线程因某些原因停止,线程池可以自动创建新的线程来维护池中线程的数量。

 

2.3 自jdk1.5开始,Java开始提供ScheduledThreadPoolExecutor类来支持周期性任务的调度,在这之前,这些工作需要依靠Timer/TimerTask或者其它第三方工具来完成。但Timer有着不少缺陷,如Timer是单线程模式,调度多个周期性任务时,如果某个任务耗时较久就会影响其它任务的调度;如果某个任务出现异常而没有被catch则可能导致唯一的线程死掉而所有任务都不会再被调度。ScheduledThreadPoolExecutor解决了很多Timer存在的缺陷。JDK1.5之前的Timer和TimerTask类已经过时了。

通过如上的介绍,可以对比一下Timer和ScheduledThreadPoolExecutor:

TimerScheduledThreadPoolExecutor
单线程多线程
单个任务执行时间影响其他任务调度多线程,不会影响
基于绝对时间基于相对时间
一旦执行任务出现异常不会捕获,其他任务得不到执行多线程,单个任务的执行不会影响其他线程

所以,在JDK1.5之后,应该没什么理由继续使用Timer进行任务调度了。


【3】ScheduledThreadPoolExecutor 工作原理

 

【4】源码

 

【5】实现例子

BusinessPool.java:

package test2;

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class BusinessPool {
	
	 private ScheduledThreadPoolExecutor executor;
	    
	    BusinessPool() {
	    }
		
		public static class BusinessPoolThreadFactory implements ThreadFactory {
			final ThreadGroup group = Thread.currentThread().getThreadGroup();
	        final AtomicInteger threadNumber = new AtomicInteger(1);
	        final String namePrefix = "business-pool";
	        
	        @Override
	        public Thread newThread(Runnable r) {
	            Thread t = new Thread(group, r,
	                                  namePrefix + threadNumber.getAndIncrement(),
	                                  0);
	            if (t.isDaemon())
	                t.setDaemon(false);
	            if (t.getPriority() != Thread.NORM_PRIORITY)
	                t.setPriority(Thread.NORM_PRIORITY);
	            return t;
	        }
		}
		
	    public void init() {
	    	this.executor = new ScheduledThreadPoolExecutor(1, new BusinessPoolThreadFactory());
	    }
	 
	    
	    public void schedule(Runnable runnable, long delay, TimeUnit unit) {
	        executor.schedule(runnable, delay, unit);
	    }
	    
	    public void execute(Runnable runnable) {
	        executor.execute(runnable);
	    }
	    
	    
}

 

test.java:

package test2;

import java.util.concurrent.TimeUnit;

public class test23 {

	public static void main(String[] args) {
		BusinessPool businessPool = new BusinessPool();
		businessPool.init();
		businessPool.schedule(new Runnable() {
			@Override
			public void run() {
				System.out.println("Hello world 0_0|||");
			}
		}, 3, TimeUnit.SECONDS);
	}

}

输出结果(延时3s执行线程):

Hello world 0_0|||

 

参考博文:https://www.jianshu.com/p/925dba9f5969

 

画外音:

保持积极,保持锻炼,保持刻苦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值