线程池
2015-11-04 12:32
381 查看
线程池的由来
线程池是线程管理的地方,因为线程的创建和回收很浪费系统资源,而线程池为线程生命周期开销问题和资源不足问题提供了解决方案。1.因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的延迟。这样,就可以立即为请求服务,使应用程序响应更快
2.通过适当地调整线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。
分类
1.固定大小的线程池
Executors.newFixedThreadPool(number)会根据数字number来创建指定大小的线程池
import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; public class Test { public static void main(String[] args) { //创建一个可重用固定线程数的线程池 ExecutorService pool = Executors.newFixedThreadPool(2); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"正在执行。。。"); } }
执行结果:
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
会从创建的线程池中选取空闲的线程来执行
2.单任务线程池
创建一个使用单个 worker 线程的线程池,以无界队列方式来运行该线程。在上例的基础上改一行创建pool对象的代码为:
ExecutorService pool = Executors.newSingleThreadExecutor();
执行结果
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
从创建的线程池中选取线程执行,如无空闲则不等待
3.可变尺寸的线程池
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。
与上面的类似,只是改动下pool的创建方式:
ExecutorService pool = Executors.newCachedThreadPool();
执行结果:
pool-1-thread-5正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-4正在执行。。。
pool-1-thread-3正在执行。。。
pool-1-thread-2正在执行。。。
会根据实际需要创建线程,无需等待。
4.固定大小计划连接池
//创建一个制定大小的延迟线程池,它可安排在给定延迟后运行命令或者定期地执行。import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) { ScheduledExecutorService pool = Executors.newScheduledThreadPool(2); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); //使用延迟执行风格的方法 pool.schedule(t4, 10, TimeUnit.MILLISECONDS); pool.schedule(t5, 10, TimeUnit.MILLISECONDS); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "正在执行。。。"); } }
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
跟类1基本一致,不同在于可延迟启动
5.单任务计划线程池
在4.基础上,做改动创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。
ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
跟2.基本一致,不同在于可延迟执行
6.自定义线程池
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) { //创建等待队列 BlockingQueue bqueue = new ArrayBlockingQueue(20); //创建一个线程执行程序,它可安排在给定延迟后执行或者定期地执行。 ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,2000,TimeUnit.MILLISECONDS,bqueue); //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口 Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); Thread t4 = new MyThread(); Thread t5 = new MyThread(); Thread t6 = new MyThread(); Thread t7 = new MyThread(); //将线程放入池中进行执行 pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); pool.execute(t6); pool.execute(t7); //关闭线程池 pool.shutdown(); } } class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "正在执行。。。"); try { Thread.sleep(100L); } catch (InterruptedException e) { e.printStackTrace(); } } }
执行结果:
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
根据ThreadPoolExecutor设置的参数创建自定义线程
给出ThreadPoolExecutor的API
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue)
参数:
corePoolSize - 池中所保存的线程数,包括空闲线程。
maximumPoolSize - 池中允许的最大线程数。
keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit - keepAliveTime 参数的时间单位。
workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
PS:线程池shutdown后必须重新申请线程池,否则会抛出异常IllegalArgumentException
整理自:http://zy116494718.iteye.com/blog/1704344
相关文章推荐
- C#线程间不能调用剪切板的解决方法
- C#多线程学习之(四)使用线程池进行多线程的自动管理
- C#线程同步的三类情景分析
- C#获取进程或线程相关信息的方法
- C#停止线程的方法
- C#子线程更新UI控件的方法实例总结
- C#线程队列用法实例分析
- C++使用CriticalSection实现线程同步实例
- c++线程池实现方法
- 基于C++实现的线程休眠代码
- VB读取线程、句柄及写入内存的API代码实例
- C#网络编程基础之进程和线程详解
- C#通过Semaphore类控制线程队列的方法
- C#多线程处理多个队列数据的方法
- C#实现线程安全的简易日志记录方法
- C#中线程同步对象的方法分析
- ASP.NET线程相关配置
- 浅析linux环境下一个进程最多能有多少个线程
- 再谈JavaScript线程
- C#实现终止正在执行的线程