package com;import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class WeiShenMe {
public static int sumValue = 0;
public static void main(String[] args) throws Exception {
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(20, 50, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
for (int i = 1; i < 100000; i++) {
threadPool.execute(new ThreadPoolTask());
}
}
}class ThreadPoolTask implements Runnable, Serializable {
ThreadPoolTask() {
}
public void run() {
System.out.println("输出:"+WeiShenMe.sumValue++);
}
}
本来我觉得 程序中【"输出:"】应该一直输出到100000 ,结果输出到200就不动了,Myeclipse显示没有执行结束,但是没有在继续输出了。我不知道我哪里写错了啊。感觉这个比较简单啊。请教大家啊。

解决方案 »

  1.   

    疑似ThreadPoolExecutor.DiscardOldestPolicy 导致
      

  2.   

    可以换成ThreadPoolExecutor.CallerRunsPolicy策略
      

  3.   

    发现个问题 sumValue 变量,貌似不是线程安全的。
    应该有多个重复的输出值。线程池没有关闭,MyEclipse当然不会显示结束了。策略选择上,会丢弃来不及执行的所有任务。
    这也是输出数据远小于任务数量的主要原因。楼主的线程池,满载任务量是50+3=53个,
    当线程池的并发量大于53时,提交的任务将被丢弃(按先进先出的顺序)。解决该问题的方法,推荐更改策略。
    缓解该问题的方法,加大线程池的满载任务量,尤其是阻塞队列的长度。
      

  4.   


    感谢啊。。
    1、是否只要用 CallerRunsPolicy 这个策略就可以了啊。就算有再多的任务都会放在队列里直到作完?
    2、怎么写sumValue 可以线程安全啊
    3、怎么关闭线程池啊?
      

  5.   

    保证线程安全可以用下AutomaticInteger
      

  6.   

    1.推荐使用CallerRunsPolicy策略,详细的几个策略,网上都有中文的API,相信很好理解。
    2.可以尝试使用volitale关键字来声明变量(没有测试过)。
          例如:public static volitale int sumValue = 0;
    3.可以调用shutdown方法来关闭线程池,
          当然,该方法会等待线程池中所有正在执行的任务都结束,才会返回。关于线程池的使用,楼主要学会参看API,现在中文的API有很多,理解起来也并不费事。