18455783050 2019-12-05 06:38 采纳率: 0%
浏览 219
已结题

两个问题,1、是线程一直没有结束,2、System.out.println("--------------dataNum = " + dataNum);这句输出的值也不争确,请指教.

public class T05_ThreadPool {
public static void main(String[] args) throws InterruptedException {
ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>();
for (int i = 0; i < 10000; i++) {
queue.offer(i);
}
AtomicInteger dataNum = new AtomicInteger(0);
ExecutorService service = Executors.newFixedThreadPool(8); //execute submit
int queueSize = queue.size();
for (int i = 0; i < queueSize; i++) {
service.execute(new Runnable(){
@Verride
public void run(){
try{
if(!queue.isEmpty()){
System.out.println("-------" + queue.poll() + "-------");
TimeUnit.MILLISECONDS.sleep(500);
dataNum.addAndGet(1);
}else{
service.shutdown();
System.out.println("--------------dataNum = " + dataNum);
}

                    }catch(Exception e){
                        e.printStackTrace();
                        service.shutdown();
                }
            }
        });
    }

    System.out.println(service);
}

}

展开全部

  • 写回答

2条回答 默认 最新

  • 轻点 别打脸 2019-12-05 08:16
    关注

    队列中一共一万个元素,你建立了一个线程池,8个线程,循环一万次也始终是这8个线程在处理,最后一个元素被某一个线程处理完后,队列虽然为空了,但你的for循环也完了,没有调用shutdown结束线程,多循环一次就可以了。
    输出结果不对,你在service.shutdown();前面加一个线程休眠,让执行中的线程执行完毕,结果自然就对了,线程shutdown是立即执行,即使有正在执行中的线程。
    若解决了你的疑问,望采纳,若还有疑问可以提出

    评论
  • 毕小宝 博客专家认证 2019-12-05 08:33
    关注

    第一个问题,线程池的 shutdown 没有执行,是因为你刚刚提交了跟队列元素一样的任务,刚刚所有任务执行时正好 poll 一个元素,执行的时候队列都是有元素的。
    应该用比队列元素多一点的线程任务,才可能在队列空的时候关闭线程池。

    for (int i = 0; i < queueSize+2; i++) {//任务数比队列元素多一点,就能保证线程池被关闭了。
    

    第二个问题,楼主贴的代码,是不可能执行到 else 分支打印 dataNum 的。但是如果在 if 分支中打印,dataNum 的确不正确。AtomicInteger 类时线程安全的,能够保证计数的正确,程序打印不准确,是因为其他线程有休眠动作,没有执行后面的 increase 时线程池就已经关闭了。

    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部