- 浏览: 869637 次
- 性别:
- 来自: 美国图森
最新评论
-
jnjeC:
jake_12345 写道大哥,这写错了吧Class.isAs ...
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
lgh1992314:
https://my.oschina.net/xianggao ...
Servlet生命周期 -
qq412796770:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
技术无涯苦作舟:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别 -
lgh1992314:
大哥,百度第一条就是你的,好歹也修改一下吧
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
线程池的作用:
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
为什么要用线程池:
- 减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务
- 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)
线程池类
package com.tdt.impl.ls; import java.util.LinkedList; /** * @project LocationGateway * @author sunnylocus * @verson 1.0.0 * @date Aug 2, 2008 * @jdk 1.4.2 */ public class ThreadPool extends ThreadGroup { private boolean isClosed = false; //线程池是否关闭 private LinkedList workQueue; //工作队列 private static int threadPoolID = 1; //线程池的id public ThreadPool(int poolSize) { //poolSize 表示线程池中的工作线程的数量 super(threadPoolID + ""); //指定ThreadGroup的名称 setDaemon(true); //继承到的方法,设置是否守护线程池 workQueue = new LinkedList(); //创建工作队列 for(int i = 0; i < poolSize; i++) { new WorkThread(i).start(); //创建并启动工作线程,线程池数量是多少就创建多少个工作线程 } } /** 向工作队列中加入一个新任务,由工作线程去执行该任务*/ public synchronized void execute(Runnable task) { if(isClosed) { throw new IllegalStateException(); } if(task != null) { workQueue.add(task);//向队列中加入一个任务 notify(); //唤醒一个正在getTask()方法中待任务的工作线程 } } /** 从工作队列中取出一个任务,工作线程会调用此方法*/ private synchronized Runnable getTask(int threadid) throws InterruptedException { while(workQueue.size() == 0) { if(isClosed) return null; System.out.println("工作线程"+threadid+"等待任务..."); wait(); //如果工作队列中没有任务,就等待任务 } System.out.println("工作线程"+threadid+"开始执行任务..."); return (Runnable) workQueue.removeFirst(); //反回队列中第一个元素,并从队列中删除 } /** 关闭线程池 */ public synchronized void closePool() { if(! isClosed) { waitFinish(); //等待工作线程执行完毕 isClosed = true; workQueue.clear(); //清空工作队列 interrupt(); //中断线程池中的所有的工作线程,此方法继承自ThreadGroup类 } } /** 等待工作线程把所有任务执行完毕*/ public void waitFinish() { synchronized (this) { isClosed = true; notifyAll(); //唤醒所有还在getTask()方法中等待任务的工作线程 } Thread[] threads = new Thread[activeCount()]; //activeCount() 返回该线程组中活动线程的估计值。 int count = enumerate(threads); //enumerate()方法继承自ThreadGroup类,根据活动线程的估计值获得线程组中当前所有活动的工作线程 for(int i =0; i < count; i++) { //等待所有工作线程结束 try { threads[i].join(); //等待工作线程结束 }catch(InterruptedException ex) { ex.printStackTrace(); } } } /** * 内部类,工作线程,负责从工作队列中取出任务,并执行 * @author sunnylocus */ private class WorkThread extends Thread { private int id; public WorkThread(int id) { //父类构造方法,将线程加入到当前ThreadPool线程组中 super(ThreadPool.this,id+""); this.id =id; } public void run() { while(! isInterrupted()) { //isInterrupted()方法继承自Thread类,判断线程是否被中断 Runnable task = null; try { task = getTask(id); //取出任务 }catch(InterruptedException ex) { ex.printStackTrace(); } //如果getTask()返回null或者线程执行getTask()时被中断,则结束此线程 if(task == null) return; try { task.run(); //运行任务 }catch(Throwable t) { t.printStackTrace(); } }// end while }// end run }// end workThread }
2.测试类
package com.tdt.test; import com.tdt.impl.ls.ThreadPool; public class ThreadPoolTest { public static void main(String[] args) throws InterruptedException { ThreadPool threadPool = new ThreadPool(3); //创建一个有个3工作线程的线程池 Thread.sleep(500); //休眠500毫秒,以便让线程池中的工作线程全部运行 //运行任务 for (int i = 0; i <=5 ; i++) { //创建6个任务 threadPool.execute(createTask(i)); } threadPool.waitFinish(); //等待所有任务执行完毕 threadPool.closePool(); //关闭线程池 } private static Runnable createTask(final int taskID) { return new Runnable() { public void run() { // System.out.println("Task" + taskID + "开始"); System.out.println("Hello world"); // System.out.println("Task" + taskID + "结束"); } }; } }
结果:
工作线程0等待任务... 工作线程1等待任务... 工作线程2等待任务... 工作线程0开始执行任务... Hello world 工作线程0等待任务... 工作线程1开始执行任务... Hello world 工作线程1等待任务... 工作线程2开始执行任务... Hello world 工作线程2等待任务... 工作线程0开始执行任务... Hello world 工作线程0等待任务... 工作线程1开始执行任务... Hello world 工作线程1等待任务... 工作线程2开始执行任务... Hello world 工作线程2等待任务...
评论
32 楼
memoryisking
2014-11-18
可以看看这篇文章,构建一个简单的线程池:http://www.strutshome.com/index.php/archives/710
31 楼
kkk3044147
2014-07-28
u010290143 写道
kkk3044147 写道
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
请问这为什么会卡在join那里 我尝试了一下 确实会卡在那里是为什么 join有用到什么特殊的地方吗?
因为waitFinish()中join的作用是等所有线程结束,这个是用其他现在还等在closePool()外,所以join这里是等不到所有线程结束的,这样就导致了死锁。
30 楼
u010290143
2014-04-10
kkk3044147 写道
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
请问这为什么会卡在join那里 我尝试了一下 确实会卡在那里是为什么 join有用到什么特殊的地方吗?
29 楼
觞S伤
2014-03-31
顶个 支持下唉····
28 楼
kkk3044147
2014-03-31
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
threadPool.closePool(); //关闭线程池
直接调closePool(),不条用waitFinish()的话程序会死锁,因为有closePool()和waitFinish()有synchronized嵌套,waitFinish中虽然已经notifyall(),但是外层的锁还没有放开,导致线程卡在join()上
27 楼
kkk3044147
2014-03-31
main中为什么要先执行waitFinish(),closePool()中不是先会执行waitFinish()的吗?
这点不明白?
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
这点不明白?
threadPool.waitFinish(); //等待所有任务执行完毕
threadPool.closePool(); //关闭线程池
26 楼
hzxlb910
2013-02-26
工作线程0等待任务...
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我执行的结果是这样,怎么1,2没有执行呢
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我执行的结果是这样,怎么1,2没有执行呢
25 楼
sunnylocus
2012-10-28
feiyang99 写道
感觉这线程池有问题啊!任务队列一个个串起来处理,并没有5个一起处理!我设了,线程数10个 还没有1个运行快啊!在run方法里设置循环10000次
你是怎么测试的?请把完整的代码发过来。
24 楼
feiyang99
2012-10-27
感觉这线程池有问题啊!任务队列一个个串起来处理,并没有5个一起处理!我设了,线程数10个 还没有1个运行快啊!在run方法里设置循环10000次
23 楼
love_ddy
2012-08-17
新手学习了,谢谢
22 楼
Stanley_Qiu
2012-08-03
我的执行结果和博主的有点不一样哦:
工作线程1等待任务…
工作线程0等待任务…
工作线程2等待任务…
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1等待任务…
工作线程0等待任务…
工作线程2等待任务…
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
工作线程1开始执行任务…
Hello World!
21 楼
Stanley_Qiu
2012-08-03
学习了,谢谢博主的分析! 楼主抱歉,我本来是想点顶的,手一抖成了踩。。。 sorry!这篇文章真的不错,再次感谢博主分享!
20 楼
sunnylocus
2012-01-13
步行的蜗牛 写道
工作线程0等待任务...
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
工作线程2开始执行任务...
Hello world
工作线程2开始执行任务...
Hello world
Hello world
工作线程1开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我的是这样的执行解果,不小心怀疑楼主……
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
工作线程2开始执行任务...
Hello world
工作线程2开始执行任务...
Hello world
Hello world
工作线程1开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我的是这样的执行解果,不小心怀疑楼主……
请贴出你的OS、OS version、JDK version
19 楼
步行的蜗牛
2012-01-12
工作线程0等待任务...
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
工作线程2开始执行任务...
Hello world
工作线程2开始执行任务...
Hello world
Hello world
工作线程1开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我的是这样的执行解果,不小心怀疑楼主……
工作线程1等待任务...
工作线程2等待任务...
工作线程0开始执行任务...
工作线程2开始执行任务...
Hello world
工作线程2开始执行任务...
Hello world
Hello world
工作线程1开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
工作线程0开始执行任务...
Hello world
我的是这样的执行解果,不小心怀疑楼主……
18 楼
sunnylocus
2011-09-06
koone 写道
大概看明白了:这个就是生产消费模式吧,使用一个工作线程池和一个任务现场队列来完成的。不过没太明白,当加入了任务线程时是怎么样通知工作线程来工作的
此时的工作线程执行wait()方法后阻塞了,使用notify()方法通知工作线程干活
17 楼
koone
2011-09-04
大概看明白了:这个就是生产消费模式吧,使用一个工作线程池和一个任务现场队列来完成的。不过没太明白,当加入了任务线程时是怎么样通知工作线程来工作的
16 楼
sunnylocus
2011-02-25
wanghonghui023 写道
楼主有点像八一队的中锋-德嘞黑啊!
因为我长的黑,他们都说我是非洲人
15 楼
wanghonghui023
2011-02-25
楼主有点像八一队的中锋-德嘞黑啊!
14 楼
sunnylocus
2010-05-13
zerxd 写道
mht19840918 写道
又一轮子~
在1.5之后,是有更好的解决方案。不过在1.4这之前,这会是一个好的方法。
说的对!
13 楼
zerxd
2010-05-12
mht19840918 写道
又一轮子~
在1.5之后,是有更好的解决方案。不过在1.4这之前,这会是一个好的方法。
发表评论
-
人在江湖:如何用代码保护自己
2011-10-12 16:30 11230现在上一点规模的 ... -
Spring freemarker页面乱码解决
2011-01-13 11:56 7478在开发过程中遇到乱码十分的头痛,如果你在开发过程中也遇 ... -
数据漂白算法研究
2010-12-07 18:05 3765你的手机是不是 ... -
理解使用static import 机制
2010-11-09 08:48 3182J2SE 1.5里引入了“Sta ... -
理解多线程设计模式
2010-11-08 17:43 10422多线程设计模式:1.Single Threaded Execu ... -
理解ThreadLocal
2010-11-03 17:04 1913ThreadLocal是什么 早在JDK 1 ... -
经验总结:高性能的数据同步
2010-11-03 10:03 6404最近在做一个银行的生产数据脱敏系统,今天写代码时遇到 ... -
用JSSE实现网络安全通信
2010-06-25 15:11 3821在网络上信息由源主机到目标主机要经过很多路由和计算机, ... -
Java实时监控日志文件并输出
2010-06-19 17:21 61122最近有一个银行数据漂白系统,要求操作人员在页面调用远端 ... -
Junit测试private方法
2010-04-28 14:09 8010package com.bill99.junit; pu ... -
保护眼睛的豆沙色
2010-03-19 09:46 3558作我们IT这行的,一天要盯着电脑看,时间长了眼睛会感觉发酸 ... -
中国联通短信网关接入程序源代码(SGIP1.2协议)
2010-01-11 12:23 42848自从我发了博文“中国联通SP业务开发总结”后有很多的朋友问 ... -
Class.isAssignableFrom(Class clz)方法 与 instanceof 关键字的区别
2009-12-24 13:14 67449原地址:http://topic.csdn.net/t/200 ... -
非阻塞通信
2009-12-03 11:43 4614对于用ServerSocket和Socket写的服务 ... -
处理线程泄露
2009-12-01 15:10 8562当一个单线程化 ... -
在Timer和ScheduledExecutorService间决择
2009-11-27 10:25 13372java.util.Timer计时器有管理任务延迟执行(& ... -
Socket通信模式:收发线程互斥
2009-11-14 19:09 8724有做过通信程序或着短信接入程序的程序员都知道,与之 ... -
ASCII码对照表
2009-11-12 11:26 2517ASCII表 ASCII值 控制字符 ASC ... -
java.net.SocketException: Software caused connection abort: recv failed 异常分析
2009-11-12 11:01 15676java.net.SocketException: Softw ... -
用State模式减少if..elseif语句
2009-11-03 17:20 7072我们在写程序的过 ...
相关推荐
Reference: 《创建Java线程池》[1],《Java线程:新特征-线程池》[2], 《Java线程池学习》[3],《线程池ThreadPoolExecutor使用简介》[4],《Java5中的线程池实例讲解》[5],《ThreadPoolExecutor使用和思考》[6] ...
2.然后根据提示运行java命令执行示例程序,观看线程池的运行结果 目标:Java中多线程技术是一个难点,但是也是一个核心技术。因为Java本身就是一个多线程语言。本人目前在给46班讲授Swing的网络编程--使用Swing来...
Java中Executors类中几种创建各类型线程池方法及简单实例
在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许在应用中自行显示的创建线程,这样一方面是线程的创建更加规范,可以合理控制开辟线程的数量;另一方面线程的细节管理交给线程池处理,优化了...
JAVA使用线程池查询大批量数据
java线程池demo ,可以使用,自己创建项目,将类复制进去,可以测试。
主要介绍了Java 线程池详解及创建简单实例的相关资料,需要的朋友可以参考下
线程池是一种线程使用模式。...这避免了在处理短时间任务时创建与销毁线程的代价。使用线程池不仅能够保证内核的充分利用,还能防止过分调度。WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。
corePoolSize:核心池的大小,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中; ...
线程池示例(包含自定义拒绝策略),演示了如何创建一个线程池,以及添加到队列的过程,先添加到工作线程,然后是缓存队列,最后是创建临时线程
Java线程池的五种使用方式源代码ThreadPoolUtils, 包含五种不同线程池的创建和使用,以及错误处理机制和线程示例
2.使用Java线程池的好处: 重用存在的线程,减少对象创建、消亡的开销,提升性能。 可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。 提供定时执行、定期执行、单线程、...
其中线程池管理器(ThreadPool Manager)的作用是创建、销毁并管理线程池,将工作线程放入线程池中;工作线程是一个可以循环执行任务的线程,在没有任务时进行等待;任务队列的作用是提供一种缓冲机制,将没有处理的...
在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来...
Java开发,Android开发,自己实现线程池,明白线程池的实现机制
26_多线程_第1天(Thread、线程创建、线程池)_讲义
主要介绍了JAVA线程池原理,结合实例形式详细分析了java线程池概念、原理、创建、使用方法及相关注意事项,需要的朋友可以参考下
从线程池概念,到线程池的创建过程以及任务执行流程,结合案例分析,用最专业的术语和精湛的文字描述让带你彻底弄懂线程池。
减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务 可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,...
Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 newFixedThreadPool 创建一个定长线程池...