前边我们讲述了:Java高并发——了解并行世界、Java高并发——多线程基础、Java高并发——多线程协作,同步控制 。从1,线程是什么?为什么需要多线程?2,Java对多线程的基础操作:线程的状态扭转,线程的创建、终止、中断、等待和通知、挂起和执行、等待结束和谦让,volatile关键字,线程组进行分类管理,守护线程,线程优先级,线程共享资源安全和synchronized进行控制。3,多线程的协作——同步控制:ReentrantLock重入锁为什么叫重入锁、中断的支持、等待时间控制、公平锁支持,Condition条件实现等待通知,Semahore信号量对一个共享资源控制多个线程的访问,ReadWriteLock读写锁对读多写少场景的支持,CountDownLatch倒计时器对线程的统一汇总,CyclicBarrier循环栅栏对线程进行循环统一汇总的支持,LockSupport利用信号量原理对线程进行阻塞和可执行…… 而,这么多线程的操作都有了,我们如何管理这些线程呢?
举个例子:工人干活,工人可以比喻为线程,工人如何干活好比单个线程的各种处理,工人如何分配公共工具,如何进行协作好比线程对共享资源的安全处理,以及各种协作通知。而工人的管理怎么办?线程的管理怎么办?总不能用的时候去招聘一个,不用的时候就解雇了吧(如果工作量不大的话,好像也行啊……)。好,下边我么看看线程池,好比工人团队。我们先看张思维导图吧,从这几个方便进行学习总结一下吧:
一,什么是线程池:
这个从上边的例子,想必已经能有很好的理解了。想必大家都用过数据库连接池,其实线程池也一样:为了避免系统频繁的创建和销毁线程(招聘解雇工人)带来的性能消耗,可以让线程得到很好的复用。当需要使用线程时从线程池取(原来是创建),当用完时归还线程池(原来是销毁)。
二,JDK中的线程池:
1,先看下JDK对线程池进行各种控制的类关系图(Executor框架),可以看着JDK的源码类,进行解读。通过Executors类方法可以看出,它的方法ExecutorService newFixedThreadPool(int nThreads)可以创建固定数量的线程池;方法ExecutorService newSingleThreadExecutor()可以创建只有一个线程的线程池;方法ExecutorService newCachedThreadPool() 可以返回一个根据实际情况调整线程数量的线程池;方法ScheduledExecutorService newSingleThreadScheduledExecutor()可以返回一个可以执行定时任务线程的线程池;方法ScheduledExecutorService newScheduledThreadPool(int corePoolSize)可以返回指定数量可以执行定时任务的线程池。当然这些方法都有重载方法,例如参数中加入自定义的ThreadFacotry等。
2,看下固定大小线程池的简单使用:
public class FixThreadPoolDemo {
public static class MyTask implements Runnable{
public void run() {
System.out.println(System.currentTimeMillis() + "Thread Name:" + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
MyTask myTask = new MyTask();
int size =5;
//下篇说下阿里技术规范插件对这个的提示问题
// ExecutorService executorService = new ThreadPoolExecutor(size,size,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
// ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("thread-call-runner-%d").build();
// ExecutorService executorService2 = new ThreadPoolExecutor(size,size,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),namedThreadFactory);
ExecutorService es = Executors.newFixedThreadPool(size);
for (int i = 0; i < 10 ; i++) {
es.submit(myTask);
}
}
}
3,看下定时任务线程池的简单使用:
public class ScheduledThreadPoolDemo {
public static void main(String[] args) {
ScheduledExecutorService executorSe