线程池-7
2.4理解ThreadPoolExecutor源码之后,再来看看线程池的使用,http://fangjian0423.github.io/2015/07/24/java-poolthread/
Executors这个帮助类提供了大概有以下几个方法:
newFixedThreadPool
newSingleThreadExecutor
newCachedThreadPool
newScheduledThreadPool
newSingleThreadScheduledExecutor
其实调用的还是ThreadPoolExecutor具体实现类,其构造方法的参数在上述已经有详述。
2.4.1newFixedThreadPool(int
nThreads)= new ThreadPoolExecutor(nThreads, nThreads, 0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue());
顾名思义,创建一个固定大小的线程池。所以其corePoolSize=maximumPoolSize= nThreads,
keepAliveTime=0L则线程空闲不会被回收。
阻塞队列是LinkedBlockingQueue,LinkedBlockingQueue是一个用链表实现的有界阻塞队列。此队列的默认和最大长度为Integer.MAX_VALUE。此队列按照先进先出的原则对元素进行排序。
2.4.2newSingleThreadExecutor()= new FinalizableDelegatedExecutorService(
new ThreadPoolExecutor(1, 1,0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue()));
FinalizableDelegatedExecutorService是个委托类,重载了finalize() {super.shutdown();},即第一次调finalize的时候会执行shutdown。里面其实创建的就是ThreadPoolExecutor。
corePoolSize=maximumPoolSize= 1,keepAliveTime=0L则线程空闲也不会被回收。阻塞队列同上,也是LinkedBlockingQueue。
2.4.3newCachedThreadPool()
= new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, newSynchronousQueue())
corePoolSize=0,maximumPoolSize = Integer.MAX_VALUE,keepAliveTime=60L即线程空闲状态下最多保持60秒
阻塞队列是SynchronousQueue,SynchronousQueue是一个不存储元素的阻塞队列。每一个put操作必须等待一个take操作,否则不能继续添加元素。SynchronousQueue可以看成是一个传球手,负责把生产者线程处理的数据直接传递给消费者线程。队列本身并不存储任何元素,非常适合于传递性场景,比如在一个线程中使用的数据,传递给另外一个线程使用,SynchronousQueue的吞吐量高于LinkedBlockingQueue 和 ArrayBlockingQueue。
2.4.4
newScheduledThreadPool(int corePoolSize) = new
ScheduledThreadPoolExecutor(corePoolSize);
= super(corePoolSize, Integer.MAX_VALUE, 0,
TimeUnit.NANOSECONDS, new DelayedWorkQueue());
corePoolSize= corePoolSize,maximumPoolSize = Integer.MAX_VALUE,keepAliveTime=0L空闲也不会被回收
阻塞队列是DelayedWorkQueue延时队列。
这个方法返回的是ScheduledExecutorService,ScheduledExecutorService是基于调度的线程池
启动调的是schedule(Runnable
command, long delay, TimeUnit unit),可以传延时时间,延时执行。最常用的调度方法 ScheduleAtFixedRate 和 ScheduleWithFixedDelay
ScheduleAtFixedRate:固定频率执行,如固定频率4秒执行一次,不管上次有没有执行,每隔4秒就执行
ScheduleWithFixedDelay:固定延迟执行,等待上一次任务执行完之后,延迟4秒再执行下一个任务。
Lock、LockSupport:
http://coderbee.net/index.php/concurrent/20131115/577
http://hovertree.com/h/bjaf/13wv7sxh.htm
http://ifeve.com/introduce-abstractqueuedsynchronizer/
AQS:源码参见以下两个链接,讲的非常清晰明了
http://www.infoq.com/cn/articles/jdk1.8-abstractqueuedsynchronizer独占锁:ReentrantLock
http://www.infoq.com/cn/articles/java8-abstractqueuedsynchronizer共享锁:CountDownLatch
http://www.cnblogs.com/zhanjindong/p/java-concurrent-package-aqs-AbstractQueuedSynchronizer.html