# ThreadPoolsDemo **Repository Path**: geguol.cc/ThreadPoolsDemo ## Basic Information - **Project Name**: ThreadPoolsDemo - **Description**: 1. 线程池构造函数 2. 线程池工厂 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2017-06-01 - **Last Updated**: 2020-12-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 线程池 [线程池详解](http://blog.csdn.net/lift_class/article/details/70216690) ## 各种队列的特性 ### 5中线程池的不同作用是因为使用了不同的队列 1. **SynchronousQueue:** > 这个队列接收到任务的时候,会直接提交给线程处理,而不保留它, > 如果所有线程都在工作怎么办?那就新建一个线程来处理这个任务! > 所以为了保证不出现<线程数达到了maximumPoolSize而不能新建线程>的错误, > 使用这个类型队列的时候,maximumPoolSize一般指定成Integer.MAX_VALUE,即无限大 2. **LinkedBlockingQueue** > 这个队列接收到任务的时候,如果当前线程数小于核心线程数,则新建线程(核心线程)处理任务; > 如果当前线程数等于核心线程数,则进入队列等待。由于这个队列没有最大值限制,即所有超过核心线程数的任务都将被添加到队列中, > 这也就导致了maximumPoolSize的设定失效,因为总线程数永远不会超过corePoolSize 3. **ArrayBlockingQueue** > 可以限定队列的长度,接收到任务的时候,如果没有达到corePoolSize的值,则新建线程(核心线程)执行任务, > 如果达到了,则入队等候,如果队列已满,则新建线程(非核心线程)执行任务,又如果总线程数到了maximumPoolSize,并且队列也满了,则发生错误 4. **DelayQueue** > 队列内元素必须实现Delayed接口,这就意味着你传进去的任务必须先实现Delayed接口。这个队列接收到任务时,首先先入队, > 只有达到了指定的延时时间,才会执行任务 ### 使用PriorityBlockingQueue 实现带有优先级的队列 > 只会对队列中的任务进行排序 > 任务Runable 需要实现compare 接口 ### 管理线程池的生命周期 shutdown()和shutdownNow()的区别 关于线程池的停止,ExecutorService为我们提供了两个方法:shutdown和shutdownNow, 这两个方法各有不同,可以根据实际需求方便的运用,如下: 1、shutdown()方法在终止前允许执行以前提交的任务。 2、shutdownNow()方法则是阻止正在任务队列中等待任务的启动并试图停止当前正在执行的任务。 ## 带暂停功能的线程池 1. 覆盖线程池的生命周期 2. 加锁 ## 关于线程的状态 [阿拉神灯](http://blog.csdn.net/nugongahou110/article/details/49967495) 1. runnable 2. callable 3. Future 4. FutureTask > 可以实现任务的取消 ## 关于线程安全 [ThreadLocal、Volatile、synchronized、Atomic关键字扫盲](http://blog.csdn.net/u010687392/article/details/50549236) [Atomic](http://blog.csdn.net/nugongahou110/article/details/49927667) ## 关于锁 > 对 synchronized 的改进 如此看来同步相当好了,是么?那么为什么 JSR 166 小组花了这么多时间来开发 java.util.concurrent.lock 框架呢? 答案很简单-同步是不错,但它并不完美。 它有一些功能性的限制 —— 它无法中断一个正在等候获得锁的线程,也无法通过投票得到锁,如果不想等下去,也就没法得到锁。 同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行, 多数情况下,这没问题(而且与异常处理交互得很好), 但是,确实存在一些非块结构的锁定更合适的情况。 ======= ## 线程间通信 1. wait 2. notify 3. notifyall 4. interrupt 5. 线程被阻塞可能是由于下面五方面的原因:(《Thinking in Java》) ````   1.调用sleep(毫秒数),使线程进入睡眠状态。在规定时间内,这个线程是不会运行的。   2.用suspend()暂停了线程的执行。除非收到resume()消息,否则不会返回“可运行”状态。   3.用wait()暂停了线程的执行。除非线程收到notify()或notifyAll()消息,否则不会变成“可运行”状态。   4.线程正在等候一些IO操作完成。   5.线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。 ```` ## CountDownLatch [CountDownLatch](http://www.importnew.com/15731.html) > CountDownLatch这个类能够使一个线程等待(一般是主线程阻塞)其他线程完成各自的工作后再执行。 > 有一个计数器会去记录这些 线程 ``` 1. Main thread start 2. Create CountDownLatch for N threads 3. Create and start N threads 4. Main thread wait on latch 5. N threads completes there tasks are returns 6. Main thread resume execution ``` > 核心方法: 1. new CountDownLatch(3) 指定线程数量 2. executor.execute(v); 3. _latch.await(); 4. 每个线程中:_latch.countDown(); > 作用 比如说同步功能:1 开三个线程去同步不同的数据 每个同步时间都不一样,最后我需要通知用户三个都同步完了 ## CyclicBarrier > CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。 > 从字面理解是循环屏障,作用是让多个线程在该屏障前等待,再一起执行后面的动作 > 作用 比如说 多线程下载,下载完多分部分后 合并文件 ## Semaphore(信号) [Semaphore](http://blog.csdn.net/shihuacai/article/details/8856526) > 用来管理信号量 1. 获取许可 semp.acquire(); 2. 释放许可 semp.release(); 3. 管理许可数量 new Semaphore(5); ## Exchanger [用于两个线程之间数据交换](http://blog.csdn.net/andycpp/article/details/8854593) 1. 只能用于两个线程 2. 每个线程都会持有 Exchanger的引用 3. Exchanger的泛型 就是要交换的数据