首页 新闻 搜索 专区 学院

ThreadPoolExecutor线程池问题

0
悬赏园豆:20 [已解决问题] 解决于 2017-11-08 16:22

  最近学习了线程池,写了个小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有啥关系?

       初接触线程池,不是很明白。望高手指点,谢谢!!

 

 

 

    

rm_rf的主页 rm_rf | 初学一级 | 园豆:6
提问于:2017-10-18 12:37
< >
分享
最佳答案
0

shutdown可没保证说已经提交的task要执行完,你那个1000是指当当前线程数大于默认线程数(第一个参数)时,多出的线程在多久没事做后被回收。

要确保线程池被关闭时可以对已经提交的task做处理,要么用awaitTermination要么在构建pool时指定其RejectedExecutionHandler的实现(实现中对未处理的task做其他处理,比如单独起线程跑完等)

收获园豆:20
Daniel Cai | 专家六级 |园豆:10374 | 2017-10-18 15:48

awaitTermination(long timeout, TimeUnit unit)确实好用,有点抓壮丁的意思。运行结果如下:

   

 

 

rm_rf | 园豆:6 (初学一级) | 2017-10-18 20:32
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册