最近学习了线程池,写了个小demo,代码如下:
MyTask.java:
package cn.ccsu.concurrent.pool; public class MyTask implements Runnable { private int taskNum; public MyTask(int num) { this.taskNum = num; } @Override synchronized public void run() { System.out.println("线程 " + this.taskNum + " 正在执行任务!!"); /*try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ System.out.println("线程 " + this.taskNum + " 执行完毕"); } }
ThreadPoolExecutorTest.java:
package cn.ccsu.concurrent.pool; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.junit.Test; public class ThreadPoolExecutorTest { @Test public void test() throws InterruptedException, ExecutionException { /* * public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long * keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) */ System.out.println("\nThreadPoolExecutorTest"); ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 14, 500, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()); int taskNum = 20; for (int i = 0; i < taskNum; i++) { Future<?> f = pool.submit(new MyTask(i)); // System.out.println(i+":"+f.get()); } System.out.println("线程池中线程数目:" + pool.getPoolSize() + ",队列中等待执行的任务数目:" + pool.getQueue().size() + ",已执行完的任务数目:" + pool.getCompletedTaskCount()); pool.shutdown(); } }
跑的时候遇到了一些问题,甚是不解
1.有的线程还没跑完,程序就结束了。注意:我用的是pool.shutdown(),not pool.shutdownNow(),如下图:
运行结果如下图:
注意看下面这张图:
队列中还有10个线程,可是只跑了5个就结束了。
shutdown()不是等待队列中的所有任务都跑完才会不再接受新任务并停止吗?甚是奇怪。
2.Sleep问题
如果让线程在跑的时候Sleep一下,就会出现如下的情况:
相关参数如下:
是不是和这个1000有啥关系?
初接触线程池,不是很明白。望高手指点,谢谢!!
shutdown可没保证说已经提交的task要执行完,你那个1000是指当当前线程数大于默认线程数(第一个参数)时,多出的线程在多久没事做后被回收。
要确保线程池被关闭时可以对已经提交的task做处理,要么用awaitTermination要么在构建pool时指定其RejectedExecutionHandler的实现(实现中对未处理的task做其他处理,比如单独起线程跑完等)
awaitTermination(long timeout, TimeUnit unit)确实好用,有点抓壮丁的意思。运行结果如下: