在路上

 找回密码
 立即注册
在路上 站点首页 学习 查看内容

Java一个简单的线程池实现

2016-12-20 13:15| 发布者: zhangjf| 查看: 445| 评论: 0

摘要: 线程池代码 import java.util.List;import java.util.Vector;public class ThreadPool { private static ThreadPool instance_ = null; //定义优先级别常数,空闲的线程按照优先级不同分别存放在三个vector中 ...

线程池代码

  1. import java.util.List;
  2. import java.util.Vector;
  3. public class ThreadPool
  4. {
  5. private static ThreadPool instance_ = null;
  6. //定义优先级别常数,空闲的线程按照优先级不同分别存放在三个vector中
  7. public static final int LOW_PRIORITY = 0;
  8. public static final int NORMAL_PRIORITY = 1;
  9. public static final int HIGH_PRIORITY = 2;
  10. //保存空闲线程的List,或者说它是"池"
  11. private List<PooledThread>[] idleThreads_;
  12. private boolean shutDown_ = false;
  13. private int threadCreationCounter_; //以创建的线程的个数
  14. private boolean debug_ = false; //是否输出调试信息
  15. //构造函数,因为这个类视作为singleton实现的,因此构造函数为私有
  16. private ThreadPool()
  17. {
  18. // 产生空闲线程.三个vector分别存放分别处在三个优先级的线程的引用
  19. List[] idleThreads = {new Vector(5), new Vector(5), new Vector(5)};
  20. idleThreads_ = idleThreads;
  21. threadCreationCounter_ = 0;
  22. }
  23. public int getCreatedThreadsCount() {
  24. return threadCreationCounter_;
  25. }
  26. //通过这个函数得到线程池类的实例
  27. public static ThreadPool instance() {
  28. if (instance_ == null)
  29. instance_ = new ThreadPool();
  30. return instance_;
  31. }
  32. public boolean isDebug() {
  33. return debug_;
  34. }
  35. //将线程repoolingThread从新放回到池中,这个方式是同步方法。
  36. //这个方法会在多线程的环境中调用,设计这个方法的目的是让工作者线程
  37. //在执行完target中的任务后,调用池类的repool()方法,
  38. //将线程自身从新放回到池中。只所以这么做是因为线程池并不能预见到
  39. //工作者线程何时会完成任务。参考PooledThread的相关代码。
  40. protected synchronized void repool(PooledThread repoolingThread)
  41. {
  42. if (!shutDown_)
  43. {
  44. if (debug_)
  45. {
  46. System.out.println("ThreadPool.repool() : repooling ");
  47. }
  48. switch (repoolingThread.getPriority())
  49. {
  50. case Thread.MIN_PRIORITY :
  51. {
  52. idleThreads_[LOW_PRIORITY].add(repoolingThread);
  53. break;
  54. }
  55. case Thread.NORM_PRIORITY :
  56. {
  57. idleThreads_[NORMAL_PRIORITY].add(repoolingThread);
  58. break;
  59. }
  60. case Thread.MAX_PRIORITY :
  61. {
  62. idleThreads_[HIGH_PRIORITY].add(repoolingThread);
  63. break;
  64. }
  65. default :
  66. throw new IllegalStateException("Illegal priority found while repooling a Thread!");
  67. }
  68. notifyAll();//通知所有的线程
  69. }
  70. else
  71. {
  72. if (debug_)
  73. {
  74. System.out.println("ThreadPool.repool() : Destroying incoming thread.");
  75. }
  76. repoolingThread.shutDown();//关闭线程
  77. }
  78. if (debug_)
  79. {
  80. System.out.println("ThreadPool.recycle() : done.");
  81. }
  82. }
  83. public void setDebug(boolean newDebug)
  84. {
  85. debug_ = newDebug;
  86. }
  87. //停止池中所有线程
  88. public synchronized void shutdown()
  89. {
  90. shutDown_ = true;
  91. if (debug_)
  92. {
  93. System.out.println("ThreadPool : shutting down ");
  94. }
  95. for (int prioIndex = 0; prioIndex <= HIGH_PRIORITY; prioIndex++)
  96. {
  97. List prioThreads = idleThreads_[prioIndex];
  98. for (int threadIndex = 0; threadIndex < prioThreads.size(); threadIndex++)
  99. {
  100. PooledThread idleThread = (PooledThread) prioThreads.get(threadIndex);
  101. idleThread.shutDown();
  102. }
  103. }
  104. notifyAll();
  105. if (debug_)
  106. {
  107. System.out.println("ThreadPool : shutdown done.");
  108. }
  109. }
  110. //以Runnable为target,从池中选择一个优先级为priority的线程创建线程
  111. //并让线程运行。
  112. public synchronized void start(Runnable target, int priority)
  113. {
  114. PooledThread thread = null; //被选出来执行target的线程
  115. List idleList = idleThreads_[priority];
  116. if (idleList.size() > 0)
  117. {
  118. //如果池中相应优先级的线程有空闲的,那么从中取出一个
  119. //设置它的target,并唤醒它
  120. //从空闲的线程队列中获取
  121. int lastIndex = idleList.size() - 1;
  122. thread = (PooledThread) idleList.get(lastIndex);
  123. idleList.remove(lastIndex);
  124. thread.setTarget(target);
  125. }
  126. //池中没有相应优先级的线程
  127. else
  128. {
  129. threadCreationCounter_++;
  130. // 创建新线程,
  131. thread = new PooledThread(target, "PooledThread #" + threadCreationCounter_, this);
  132. // 新线程放入池中
  133. switch (priority)
  134. {
  135. case LOW_PRIORITY :
  136. {
  137. thread.setPriority(Thread.MIN_PRIORITY);
  138. break;
  139. }
  140. case NORMAL_PRIORITY :
  141. {
  142. thread.setPriority(Thread.NORM_PRIORITY);
  143. break;
  144. }
  145. case HIGH_PRIORITY :
  146. {
  147. thread.setPriority(Thread.MAX_PRIORITY);
  148. break;
  149. }
  150. default :
  151. {
  152. thread.setPriority(Thread.NORM_PRIORITY);
  153. break;
  154. }
  155. }
  156. //启动这个线程
  157. thread.start();
  158. }
  159. }
  160. }
复制代码

工作者线程代码:

  1. public class PooledThread extends Thread
  2. {
  3. private ThreadPool pool_; // 池中线程需要知道自己所在的池
  4. private Runnable target_; // 线程的任务
  5. private boolean shutDown_ = false;
  6. private boolean idle_ = false;//设置是否让线程处于等待状态
  7. private PooledThread() {
  8. super();
  9. }
  10. private PooledThread(Runnable target)
  11. {
  12. super(target); //初始化父类
  13. }
  14. private PooledThread(Runnable target, String name)
  15. {
  16. super(target, name);
  17. }
  18. public PooledThread(Runnable target, String name, ThreadPool pool)
  19. {
  20. super(name);
  21. pool_ = pool;
  22. target_ = target;
  23. }
  24. private PooledThread(String name)
  25. {
  26. super(name);//初始化父类
  27. }
  28. private PooledThread(ThreadGroup group, Runnable target)
  29. {
  30. super(group, target);
  31. }
  32. private PooledThread(ThreadGroup group, Runnable target, String name)
  33. {
  34. super(group, target, name);
  35. }
  36. private PooledThread(ThreadGroup group, String name)
  37. {
  38. super(group, name);
  39. }
  40. public java.lang.Runnable getTarget()
  41. {
  42. return target_;
  43. }
  44. public boolean isIdle()
  45. {
  46. return idle_;//返回当前的状态
  47. }
  48. //工作者线程与通常线程不同之处在于run()方法的不同。通常的线程,
  49. //完成线程应该执行的代码后,自然退出,线程结束。
  50. //虚拟机在线程结束后收回分配给线程的资源,线程对象被垃圾回收。]
  51. //而这在池化的工作者线程中是应该避免的,否则线程池就失去了意义。
  52. //作为可以被放入池中并重新利用的工作者线程,它的run()方法不应该结束,
  53. //随意,在随后可以看到的实现中,run()方法执行完target对象的代码后,
  54. //就将自身repool(),然后调用wait()方法,使自己睡眠而不是退出循环和run()。
  55. //这就使线程池实现的要点。
  56. public void run()
  57. {
  58. // 这个循环不能结束,除非池类要求线程结束
  59. // 每一次循环都会执行一次池类分配给的任务target
  60. while (!shutDown_)
  61. {
  62. idle_ = false;
  63. if (target_ != null)
  64. {
  65. target_.run(); // 运行target中的代码
  66. }
  67. idle_ = true;
  68. try
  69. {
  70. //线程通知池重新将自己放回到池中
  71. pool_.repool(this); //
  72. //进入池中后睡眠,等待被唤醒执行新的任务,
  73. //这里是线程池中线程于普通线程的run()不同的地方。
  74. synchronized (this)
  75. {
  76. wait();
  77. }
  78. }
  79. catch (InterruptedException ie)
  80. {
  81. }
  82. idle_ = false;
  83. }
  84. //循环这里不能结束,否则线程结束,资源被VM收回,
  85. //就无法起到线程池的作用了
  86. }
  87. public synchronized void setTarget(java.lang.Runnable newTarget)
  88. {//设置新的target,并唤醒睡眠中的线程
  89. target_ = newTarget; // 新任务
  90. notifyAll(); // 唤醒睡眠的线程
  91. }
  92. public synchronized void shutDown()
  93. {
  94. shutDown_ = true;
  95. notifyAll();
  96. }
  97. }
复制代码

测试代码:

  1. public static void main(String[] args)
  2. {
  3. System.out.println("Testing ThreadPool ");
  4. System.out.println("Creating ThreadPool ");
  5. ThreadPool pool = ThreadPool.instance();
  6. pool.setDebug(true);
  7. class TestRunner implements Runnable
  8. {
  9. public int count = 0;
  10. public void run()
  11. {
  12. System.out.println("Testrunner sleeping 5 seconds ");
  13. //此方法使本线程睡眠5秒
  14. synchronized (this)
  15. {
  16. try
  17. {
  18. wait(5000);//等待5秒时间
  19. }
  20. catch (InterruptedException ioe)
  21. {
  22. }
  23. }
  24. System.out.println("Testrunner leaving ");
  25. count++;
  26. }
  27. }
  28. System.out.println("Starting a new thread ");
  29. TestRunner runner = new TestRunner();
  30. pool.start(runner, pool.HIGH_PRIORITY);
  31. System.out.println("count : " + runner.count);
  32. System.out.println("Thread count : " + pool.getCreatedThreadsCount());
  33. pool.shutdown();
  34. }
  35. }
复制代码

结果

Testing ThreadPool
Creating ThreadPool

Starting a new thread

Testrunner sleeping
5 seconds
count :
0
Thread count :
1
ThreadPool : shutting down

ThreadPool : shutdown done
.
Testrunner leaving

ThreadPool
.repool() : Destroying incoming thread.
ThreadPool
.recycle() : done.



最新评论

小黑屋|在路上 ( 蜀ICP备15035742号-1 

;

GMT+8, 2025-7-8 09:05

Copyright 2015-2025 djqfx

返回顶部