- 浏览: 205389 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (100)
- java设计模式学习 (1)
- javascript (2)
- sqlserver (3)
- java基础 (18)
- spring (8)
- webwork (3)
- itext (4)
- xstream (1)
- freemarker (2)
- jsp (6)
- hibernate (7)
- jquery (1)
- json (1)
- poi (2)
- iprocess (1)
- bw (1)
- bpm (0)
- java2word (0)
- ireport (1)
- Struts2.0 (13)
- webservice (6)
- j2ee基础 (7)
- jms (3)
- protocol buffer (3)
- jfreechart (1)
- spring mvc (0)
- http编程机制探析 (1)
- pb (2)
- oracle (0)
- sso (0)
- mybatis (0)
- ssl与ca认证 (0)
- cas (1)
最新评论
-
mayucai:
这个博客写的我是真服,写了一大堆,结果最后来一句这是错的。
poi获取excel和word总页数 -
iris_1992:
2005年以前,国外开原报表完全碾压国产软件,但是现在国内软件 ...
ireport与jasperreports开发总结 -
高攀sky:
...
Servlet中的八大Listener -
rmn190:
多谢, 试了N多个后, 终于参考您的内容, 设置出来了。老天开 ...
ireport与jasperreports开发总结 -
辣油_:
System.out.println("草 ...
Spring-JNDI配置
1、线程池简介:
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3
的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。
代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了
[java] view plaincopy
01.package mine.util.thread;
02.
03.import java.util.LinkedList;
04.import java.util.List;
05.
06./**
07. * 线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息
08. */
09.public final class ThreadPool {
10. // 线程池中默认线程的个数为5
11. private static int worker_num = 5;
12. // 工作线程
13. private WorkThread[] workThrads;
14. // 未处理的任务
15. private static volatile int finished_task = 0;
16. // 任务队列,作为一个缓冲,List线程不安全
17. private List<Runnable> taskQueue = new LinkedList<Runnable>();
18. private static ThreadPool threadPool;
19.
20. // 创建具有默认线程个数的线程池
21. private ThreadPool() {
22. this(5);
23. }
24.
25. // 创建线程池,worker_num为线程池中工作线程的个数
26. private ThreadPool(int worker_num) {
27. ThreadPool.worker_num = worker_num;
28. workThrads = new WorkThread[worker_num];
29. for (int i = 0; i < worker_num; i++) {
30. workThrads[i] = new WorkThread();
31. workThrads[i].start();// 开启线程池中的线程
32. }
33. }
34.
35. // 单态模式,获得一个默认线程个数的线程池
36. public static ThreadPool getThreadPool() {
37. return getThreadPool(ThreadPool.worker_num);
38. }
39.
40. // 单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数
41. // worker_num<=0创建默认的工作线程个数
42. public static ThreadPool getThreadPool(int worker_num1) {
43. if (worker_num1 <= 0)
44. worker_num1 = ThreadPool.worker_num;
45. if (threadPool == null)
46. threadPool = new ThreadPool(worker_num1);
47. return threadPool;
48. }
49.
50. // 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
51. public void execute(Runnable task) {
52. synchronized (taskQueue) {
53. taskQueue.add(task);
54. taskQueue.notify();
55. }
56. }
57.
58. // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
59. public void execute(Runnable[] task) {
60. synchronized (taskQueue) {
61. for (Runnable t : task)
62. taskQueue.add(t);
63. taskQueue.notify();
64. }
65. }
66.
67. // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
68. public void execute(List<Runnable> task) {
69. synchronized (taskQueue) {
70. for (Runnable t : task)
71. taskQueue.add(t);
72. taskQueue.notify();
73. }
74. }
75.
76. // 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
77. public void destroy() {
78. while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成,就先睡会吧
79. try {
80. Thread.sleep(10);
81. } catch (InterruptedException e) {
82. e.printStackTrace();
83. }
84. }
85. // 工作线程停止工作,且置为null
86. for (int i = 0; i < worker_num; i++) {
87. workThrads[i].stopWorker();
88. workThrads[i] = null;
89. }
90. threadPool=null;
91. taskQueue.clear();// 清空任务队列
92. }
93.
94. // 返回工作线程的个数
95. public int getWorkThreadNumber() {
96. return worker_num;
97. }
98.
99. // 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成
100. public int getFinishedTasknumber() {
101. return finished_task;
102. }
103.
104. // 返回任务队列的长度,即还没处理的任务个数
105. public int getWaitTasknumber() {
106. return taskQueue.size();
107. }
108.
109. // 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
110. @Override
111. public String toString() {
112. return "WorkThread number:" + worker_num + " finished task number:"
113. + finished_task + " wait task number:" + getWaitTasknumber();
114. }
115.
116. /**
117. * 内部类,工作线程
118. */
119. private class WorkThread extends Thread {
120. // 该工作线程是否有效,用于结束该工作线程
121. private boolean isRunning = true;
122.
123. /*
124. * 关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待
125. */
126. @Override
127. public void run() {
128. Runnable r = null;
129. while (isRunning) {// 注意,若线程无效则自然结束run方法,该线程就没用了
130. synchronized (taskQueue) {
131. while (isRunning && taskQueue.isEmpty()) {// 队列为空
132. try {
133. taskQueue.wait(20);
134. } catch (InterruptedException e) {
135. e.printStackTrace();
136. }
137. }
138. if (!taskQueue.isEmpty())
139. r = taskQueue.remove(0);// 取出任务
140. }
141. if (r != null) {
142. r.run();// 执行任务
143. }
144. finished_task++;
145. r = null;
146. }
147. }
148.
149. // 停止工作,让该线程自然执行完run方法,自然结束
150. public void stopWorker() {
151. isRunning = false;
152. }
153. }
154.}
测试代码:
[java] view plaincopy
01.package mine.util.thread;
02.
03.//测试线程池
04.public class TestThreadPool {
05. public static void main(String[] args) {
06. // 创建3个线程的线程池
07. ThreadPool t = ThreadPool.getThreadPool(3);
08. t.execute(new Runnable[] { new Task(), new Task(), new Task() });
09. t.execute(new Runnable[] { new Task(), new Task(), new Task() });
10. System.out.println(t);
11. t.destroy();// 所有线程都执行完成才destory
12. System.out.println(t);
13. }
14.
15. // 任务类
16. static class Task implements Runnable {
17. private static volatile int i = 1;
18.
19. @Override
20. public void run() {// 执行任务
21. System.out.println("任务 " + (i++) + " 完成");
22. }
23. }
24.}
运行结果:
WorkThread number:3 finished task number:0 wait task number:6
任务 1 完成
任务 2 完成
任务 3 完成
任务 4 完成
任务 5 完成
任务 6 完成
WorkThread number:3 finished task number:6 wait task number:0
分析:由于并没有任务接口,传入的可以是自定义的任何任务,所以线程池并不能准确的判断该任务是否真正的已经完成(真正完成该任务是这个任务的run方法执行完毕),只能知道该任务已经出了任务队列,正在执行或者已经完成。
2、java类库中提供的线程池简介:
java提供的线程池更加强大,相信理解线程池的工作原理,看类库中的线程池就不会感到陌生了。
其他具体内容查看jdk帮助或看jdk源代码吧。。。
多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力。
假设一个服务器完成一项任务所需时间为:T1 创建线程时间,T2 在线程中执行任务的时间,T3 销毁线程时间。
如果:T1 + T3 远大于 T2,则可以采用线程池,以提高服务器性能。
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3
的开销了。
线程池不仅调整T1,T3产生的时间段,而且它还显著减少了创建线程的数目,看一个例子:
假设一个服务器一天要处理50000个请求,并且每个请求需要一个单独的线程完成。在线程池中,线程数一般是固定的,所以产生线程总数不会超过线程池中线程的数目,而如果服务器不利用线程池来处理这些请求则线程总数为50000。一般线程池大小是远小于50000。所以利用线程池的服务器程序不会为了创建50000而在处理请求时浪费时间,从而提高效率。
代码实现中并没有实现任务接口,而是把Runnable对象加入到线程池管理器(ThreadPool),然后剩下的事情就由线程池管理器(ThreadPool)来完成了
[java] view plaincopy
01.package mine.util.thread;
02.
03.import java.util.LinkedList;
04.import java.util.List;
05.
06./**
07. * 线程池类,线程管理器:创建线程,执行任务,销毁线程,获取线程基本信息
08. */
09.public final class ThreadPool {
10. // 线程池中默认线程的个数为5
11. private static int worker_num = 5;
12. // 工作线程
13. private WorkThread[] workThrads;
14. // 未处理的任务
15. private static volatile int finished_task = 0;
16. // 任务队列,作为一个缓冲,List线程不安全
17. private List<Runnable> taskQueue = new LinkedList<Runnable>();
18. private static ThreadPool threadPool;
19.
20. // 创建具有默认线程个数的线程池
21. private ThreadPool() {
22. this(5);
23. }
24.
25. // 创建线程池,worker_num为线程池中工作线程的个数
26. private ThreadPool(int worker_num) {
27. ThreadPool.worker_num = worker_num;
28. workThrads = new WorkThread[worker_num];
29. for (int i = 0; i < worker_num; i++) {
30. workThrads[i] = new WorkThread();
31. workThrads[i].start();// 开启线程池中的线程
32. }
33. }
34.
35. // 单态模式,获得一个默认线程个数的线程池
36. public static ThreadPool getThreadPool() {
37. return getThreadPool(ThreadPool.worker_num);
38. }
39.
40. // 单态模式,获得一个指定线程个数的线程池,worker_num(>0)为线程池中工作线程的个数
41. // worker_num<=0创建默认的工作线程个数
42. public static ThreadPool getThreadPool(int worker_num1) {
43. if (worker_num1 <= 0)
44. worker_num1 = ThreadPool.worker_num;
45. if (threadPool == null)
46. threadPool = new ThreadPool(worker_num1);
47. return threadPool;
48. }
49.
50. // 执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
51. public void execute(Runnable task) {
52. synchronized (taskQueue) {
53. taskQueue.add(task);
54. taskQueue.notify();
55. }
56. }
57.
58. // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
59. public void execute(Runnable[] task) {
60. synchronized (taskQueue) {
61. for (Runnable t : task)
62. taskQueue.add(t);
63. taskQueue.notify();
64. }
65. }
66.
67. // 批量执行任务,其实只是把任务加入任务队列,什么时候执行有线程池管理器觉定
68. public void execute(List<Runnable> task) {
69. synchronized (taskQueue) {
70. for (Runnable t : task)
71. taskQueue.add(t);
72. taskQueue.notify();
73. }
74. }
75.
76. // 销毁线程池,该方法保证在所有任务都完成的情况下才销毁所有线程,否则等待任务完成才销毁
77. public void destroy() {
78. while (!taskQueue.isEmpty()) {// 如果还有任务没执行完成,就先睡会吧
79. try {
80. Thread.sleep(10);
81. } catch (InterruptedException e) {
82. e.printStackTrace();
83. }
84. }
85. // 工作线程停止工作,且置为null
86. for (int i = 0; i < worker_num; i++) {
87. workThrads[i].stopWorker();
88. workThrads[i] = null;
89. }
90. threadPool=null;
91. taskQueue.clear();// 清空任务队列
92. }
93.
94. // 返回工作线程的个数
95. public int getWorkThreadNumber() {
96. return worker_num;
97. }
98.
99. // 返回已完成任务的个数,这里的已完成是只出了任务队列的任务个数,可能该任务并没有实际执行完成
100. public int getFinishedTasknumber() {
101. return finished_task;
102. }
103.
104. // 返回任务队列的长度,即还没处理的任务个数
105. public int getWaitTasknumber() {
106. return taskQueue.size();
107. }
108.
109. // 覆盖toString方法,返回线程池信息:工作线程个数和已完成任务个数
110. @Override
111. public String toString() {
112. return "WorkThread number:" + worker_num + " finished task number:"
113. + finished_task + " wait task number:" + getWaitTasknumber();
114. }
115.
116. /**
117. * 内部类,工作线程
118. */
119. private class WorkThread extends Thread {
120. // 该工作线程是否有效,用于结束该工作线程
121. private boolean isRunning = true;
122.
123. /*
124. * 关键所在啊,如果任务队列不空,则取出任务执行,若任务队列空,则等待
125. */
126. @Override
127. public void run() {
128. Runnable r = null;
129. while (isRunning) {// 注意,若线程无效则自然结束run方法,该线程就没用了
130. synchronized (taskQueue) {
131. while (isRunning && taskQueue.isEmpty()) {// 队列为空
132. try {
133. taskQueue.wait(20);
134. } catch (InterruptedException e) {
135. e.printStackTrace();
136. }
137. }
138. if (!taskQueue.isEmpty())
139. r = taskQueue.remove(0);// 取出任务
140. }
141. if (r != null) {
142. r.run();// 执行任务
143. }
144. finished_task++;
145. r = null;
146. }
147. }
148.
149. // 停止工作,让该线程自然执行完run方法,自然结束
150. public void stopWorker() {
151. isRunning = false;
152. }
153. }
154.}
测试代码:
[java] view plaincopy
01.package mine.util.thread;
02.
03.//测试线程池
04.public class TestThreadPool {
05. public static void main(String[] args) {
06. // 创建3个线程的线程池
07. ThreadPool t = ThreadPool.getThreadPool(3);
08. t.execute(new Runnable[] { new Task(), new Task(), new Task() });
09. t.execute(new Runnable[] { new Task(), new Task(), new Task() });
10. System.out.println(t);
11. t.destroy();// 所有线程都执行完成才destory
12. System.out.println(t);
13. }
14.
15. // 任务类
16. static class Task implements Runnable {
17. private static volatile int i = 1;
18.
19. @Override
20. public void run() {// 执行任务
21. System.out.println("任务 " + (i++) + " 完成");
22. }
23. }
24.}
运行结果:
WorkThread number:3 finished task number:0 wait task number:6
任务 1 完成
任务 2 完成
任务 3 完成
任务 4 完成
任务 5 完成
任务 6 完成
WorkThread number:3 finished task number:6 wait task number:0
分析:由于并没有任务接口,传入的可以是自定义的任何任务,所以线程池并不能准确的判断该任务是否真正的已经完成(真正完成该任务是这个任务的run方法执行完毕),只能知道该任务已经出了任务队列,正在执行或者已经完成。
2、java类库中提供的线程池简介:
java提供的线程池更加强大,相信理解线程池的工作原理,看类库中的线程池就不会感到陌生了。
其他具体内容查看jdk帮助或看jdk源代码吧。。。
发表评论
-
java线程安全总结
2014-02-27 16:56 568关于java线程安全,网上有很多资料,我只想从自己的角度总结对 ... -
Java内存溢出的详细解决方案
2013-03-26 10:50 0一、内存溢出类型 1、j ... -
内存分区
2013-03-26 10:12 0Java代码 内存可分为3个区:堆(heap)、栈(sta ... -
持续集成工具hudson(Continuous Integration )CI
2013-03-20 13:19 947一.什么是持续集成 持 ... -
收录各种猥琐的Java笔试/面试题目
2013-03-19 15:23 809本文收录各种猥琐的Java笔试/面试题,一些比较容易忘记的,不 ... -
what is difference between hashmap and hashtable
2013-02-28 14:31 01.Hashmap is unSynchronized and ... -
java引用类型和值类型
2012-07-27 13:58 942Java传值还是传引用终极解释,还是看老外解释的清楚啊。 ... -
在Java中gsm modem发短信
2011-11-13 17:21 0JAVA发送SMS短信有两种方法:一是通过运营商的网关;二是通 ... -
java枚举类型
2011-10-27 11:00 972枚举类型是JDK5.0的新特征。Sun引进了一个全新的关键字e ... -
JDK1.5新特性介绍
2011-10-27 10:51 706“JDK1.5”(开发代号猛 ... -
java中的enum类型与单态设计模式
2011-10-27 10:40 788单态设计模式有三种做法: 1.声明公有实例为public 2. ... -
谨慎地实现Serializable
2011-10-27 10:15 1153《Effective Java中文版( ... -
Java中static、final用法小结
2011-04-12 15:24 967一、final 1.final变量: ... -
j2se代码性能技巧
2011-03-04 17:00 0.JAVA开发工具集(JDK) ... -
Map与List性能比较
2011-03-04 16:23 103081.Collection接口与Map的总体框架图 Colle ... -
String.format方法使用
2011-03-04 11:45 9609一.常规类型、字符类型和数值类型的格式说明符的语法如下:%[ ... -
HttpServletResponseWrapper获取jsp的输出内容
2011-02-17 10:17 0主题:(转)用HttpServletResponseWrapp ... -
java hotswap(java热部署)
2011-01-04 14:33 1981安装步骤: 1、 在 windows 启动安装程序,在控制 ... -
common-BeanUtils使用
2010-12-17 15:16 14521。在審核過程中,我們 ... -
java压缩加密
2010-12-06 12:03 36651。首先下载winzipaes.jar(h ...
相关推荐
讲述VC使用线程池的原理以及怎样创建一个通用线程池的方法
线程池原理及创建(C++实现)线程池原理及创建(C++实现)线程池原理及创建(C++实现)线程池原理及创建(C++实现)
线程池原理及创建(C++实现)
Java线程池的原理与实现 Java线程池的原理与实现
线程池原理及创建(C++实现);学习线程池等池类工具的参考资料,比较浅显易懂。网上收集,供交流学习。
面向构件基于和欣内核的进程_线程池原理与实现.pdf
java线程池的原理和实现,挺全面的,分享给大家!
本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关。另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整线程池...文章的最后,我们给出部分实现。
详细论述了线程池的原理,以及实现过程的分析
主要介绍了Django异步任务线程池实现原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
瞎写的线程池原理,没啥用,只是留着自己以后想看看,在技术博客中都有.不要下载,乱七八糟的,怕你们吐槽.
该文档为c++开发的线程池,可以作为参考
JAVA线程池的原理与实现.pdf
5.4 并发线程池底层原理及实现详解(2).mp4
5.4 并发线程池底层原理及实现详解(1).mp4
线程池的实现以及底层原理.docx
详细介绍了VC++下线程池的原理及创建步骤
易语言简易线程池的实现。 ——V雪落有声V原创。转载请保留。前文:。为了能充分理解本篇文章的内容,需要了解的知识如下:。1.事件对象的使用:http://baike.baidu.com/view/751499.htm。2.信号量的使用:...