首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中使用Countdownlatch闩锁和Executor时未获得预期输出

在java中使用Countdownlatch闩锁和Executor时未获得预期输出
EN

Stack Overflow用户
提问于 2013-02-26 17:35:38
回答 3查看 505关注 0票数 0

我对Java Multithreading非常陌生。尝试在Java线程中学习计数锁存和执行程序,并实现了以下代码-

代码语言:javascript
复制
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorBasicFramework {


    class MyThread extends Thread{

        int iCount ; String name;
        CountDownLatch latch;

        public MyThread(int iCount, String name, CountDownLatch latch) {
            super();
            this.iCount = iCount;
            this.name = name;
            this.latch = latch;         
        }

        @Override
        public void run() {
            for(int i=0;i<10;i++){
                System.out.println(name+" Printing .... "+ ++iCount+" L "+latch.getCount());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }
            latch.countDown();

        }

    }

    public ExecutorBasicFramework() {
        createThread();
    }


    private void createThread() {
        ExecutorService exec = Executors.newFixedThreadPool(10);
        CountDownLatch latch = new CountDownLatch(10);
        for(int i=0;i<10;i++){          
            MyThread thread = new MyThread(i*10, ""+i,latch);
            exec.execute(thread);

            try {
                latch.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        exec.shutdownNow();     

    }

    public static void main(String[] args) {
        new ExecutorBasicFramework();
    }

}

接下来的产出是-

代码语言:javascript
复制
0 Printing .... 1 L 10
0 Printing .... 2 L 10
0 Printing .... 3 L 10
0 Printing .... 4 L 10
0 Printing .... 5 L 10
0 Printing .... 6 L 10
0 Printing .... 7 L 10
0 Printing .... 8 L 10
0 Printing .... 9 L 10
0 Printing .... 10 L 10

然后流动就像继续等待。我的预期输出和上面一样,但是在打印0之后,它应该在1到9之间打印类似的输出,然后程序应该停止。

我认为计数锁定是等待和等待,它不会增加下一个计数器的执行者。所以我无法得到预期的输出。我期待着产出就像-

代码语言:javascript
复制
0 Printing .... 1 L 10
0 Printing .... 2 L 10
0 Printing .... 3 L 10
0 Printing .... 4 L 10
0 Printing .... 5 L 10
0 Printing .... 6 L 10
0 Printing .... 7 L 10
0 Printing .... 8 L 10
0 Printing .... 9 L 10
0 Printing .... 10 L 10


1 Printing .... 11 L 9
1 Printing .... 12 L 9
1 Printing .... 13 L 9
1 Printing .... 14 L 9
1 Printing .... 15 L 9
1 Printing .... 16 L 9
1 Printing .... 17 L 9
1 Printing .... 18 L 9
1 Printing .... 19 L 9
1 Printing .... 20 L 9

and So on ... 
2 Printing .... 21 L 8
2 Printing .... 22 L 8
2 Printing .... 23 L 8

对于锁存的每个递减计数器,下一个线程池必须执行一个计数到10。然后,它必须再次减少锁存计数器,并且进程再次重复,直到线程9完成相同的操作。

请提出一些建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-26 20:17:10

如果您打算使用CountDownLatchmain()方法等待所有线程的执行,那么您应该将latch.await()移到提交线程的循环之外。另外,在不再次设置中断标志的情况下,您不应该吃InterruptedException。(见本文)。

修正后的结果如下:

代码语言:javascript
复制
for(int i=0;i<10;i++){          
    MyThread thread = new MyThread(i*10, ""+i,latch);
    exec.execute(thread);
}
try {
    latch.await();
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();
}

虽然这肯定会起作用,但在使用ExecutorService时,Latch是等待在另一个线程上运行的可运行线程的次优方式。如果使用submit()而不是execute(),则可以使用submit()返回的Future通过调用提交的Runnable来等待提交Runnable的完成。

票数 1
EN

Stack Overflow用户

发布于 2013-02-26 17:39:13

因此,您正在配置一个10 new CountDownLatch(10)的倒计时值,但是您的代码只会在每个线程中减少一次。当你只分了一个线程后,你就会等待锁锁,但它是在9点。

代码语言:javascript
复制
MyThread thread = new MyThread(i*10, ""+i,latch);
exec.execute(thread);
latch.await();

不确定您的意图是什么,但也许latch.countDown();应该在线程中的for循环中呢?

代码语言:javascript
复制
for(int i=0;i<10;i++) {
   ...
   // if you want the latch to count-down 10 times, it should be inside the loop
   latch.countDown();
}
// it should not go here, outside the loop

如果目标是等待所有作业完成,则可以使用ExecutorService.awaitTermination(...)方法来完成:

代码语言:javascript
复制
// submit jobs in loop
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

另外,您不应该在您的Thread类中扩展MyThread。您应该实现Runnable。代码工作的唯一原因是Thread也实现了Runnable,但是MyThread不应该是ThreadExecutorService采用RunnableCallable,而不是Thread。它在服务内部为您管理线程。

票数 3
EN

Stack Overflow用户

发布于 2013-02-27 15:27:24

谢谢大家的投入。我找到了一个更简单的解决方案来达到我的期望。我只是使用了Executors.newSingleThreadExecutor();,因为它已经确保了所有任务都将被保证按顺序执行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15095582

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档