0

我对 Java多线程非常陌生。尝试在 Java 线程中学习 countdownlatch 和 executor 并实现以下代码-

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();
    }

}

输出如下 -

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 的类似输出,然后程序应该停止。

我认为倒计时正在等待和等待,它不会增加执行器的下一个计数器。所以我无法获得预期的输出。我期待输出像 -

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 完成相同

请提出一些意见。

4

3 回答 3

3

因此,您将倒计时值配置为 10 new CountDownLatch(10),但您的代码仅在每个线程中递减一次。在你只分叉 1 个线程后,你等待闩锁,但它位于 9。

MyThread thread = new MyThread(i*10, ""+i,latch);
exec.execute(thread);
latch.await();

不确定您的意图,但也许latch.countDown();应该线程的 for 循环内?

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(...)方法:

// submit jobs in loop
exec.shutdown();
exec.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);

此外,您Thread应该在MyThread课堂上进行扩展。你应该实施Runnable. 您的代码有效的唯一原因是它Thread也实现RunnableMyThread应该是. 需要 a或 a ,而不是 a 。它在服务内部为您管理线程。ThreadExecutorServiceRunnableCallableThread

于 2013-02-26T17:39:13.593 回答
1

如果您的意图是使用CountDownLatch让该main()方法等到所有线程都已执行,那么您应该将提交线程的循环移到latch.await() 外部。InterruptedException此外,如果没有再次设置中断标志,您不应该吃掉。(见这篇文章)。

更正如下所示:

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. 如果你使用submit()而不是execute()你可以使用Futurereturned bysubmit()来等待提交完成,Runnable通过调用get()就可以了。

于 2013-02-26T20:17:10.030 回答
0

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

于 2013-02-27T15:27:24.260 回答