程序如何保证使用executor框架同时执行多个线程



我正在尝试同时完美地执行5个线程。但从下面的输出来看,我认为他们是在同一时间开始的,但不是同时开始的,因为年龄计数器总是以5计数结束。如果他们同时执行real年龄输出必须相同的群体。通过realconcurrent或perfect Same time,我认为所有通过1的5个线程都是age,并且所有线程都打印相同的age而不是递增值。请纠正我。

public class ExecutorServiceTester {
public static void main(String args[]) throws InterruptedException {
    ExecutorServiceTester tester = new ExecutorServiceTester();
    tester.executeTester();
}
private void executeTester() throws InterruptedException {
    ExecutorService executorService = Executors.newFixedThreadPool(10);
    Runnable worker = new MyRunnable(1);
    for (int i = 0; i < 10; i++) {
        executorService.execute(worker);
    } executorService.shutdown();
}
public static class MyRunnable implements Runnable {
    int age = 0;
    public MyRunnable(int count) {
        this.age = count;
    }
    @Override
    public void run() {
        System.out.println(new Timestamp(new Date().getTime())+" ThreadName:"+Thread.currentThread().getName()
                + " Age " + age++);
    }
} }

输出:

2015-03-23 02:02:18.243 ThreadName:pool-1-thread-1 Age 1
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-5 Age 3
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-3 Age 5
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-2 Age 2
2015-03-23 02:02:18.243 ThreadName:pool-1-thread-4 Age 4

尝试使用Executors时。newCachedThreadPool();并将数字增加到12,OUTPUT在之后引起了一些兴趣

2015-03-23 02:17:57.189 **ThreadName:pool-1-thread-4 Age 1**
2015-03-23 02:17:57.189 ThreadName:pool-1-thread-10 Age 3
2015-03-23 02:17:57.189 ThreadName:pool-1-thread-12 Age 2
2015-03-23 02:17:57.189 **ThreadName:pool-1-thread-11 Age 1** ...

所有线程使用同一计数器的原因是您向它们提供了相同的Runnable实例。只需为循环中的每个线程创建一个新线程即可:

for (int i = 0; i < 10; i++) {
    Runnable worker = new MyRunnable(1);
    executorService.execute(worker);
}

这可能并不理想,但如果您需要它们完全对齐,我会设置一些类型的Mark。使用System.nanoTime()可以将当前时间降到纳秒。给它一段时间等待,比如整整一秒(1_000_000_0000)纳秒。确保延迟足够长(无论是什么),以便所有线程都能初始化并到达等待点。在创建时将该MarkTime传递给每个线程。然后让每个线程都有这样的函数:

while(System.nanoTime() < MarkTime){
    // do nothing
}

Boom,当时间到了,所有线程都关闭并运行,协调到纳秒。

就像跑步者在起跑线上为比赛做准备。他们都在不同的时间到达终点,但都是在同一个先发球员的手枪射击开始的。

此外,正如@Keppil所说,您可能希望为每个版本创建一个新的线程实例,而不是同一实例的5个副本。这样你就可以确保它们同时独立运行。

或者:另一种方法是在父类中设置布尔值,将其设置为false,在所有线程都处于活动状态后,让它们检查该布尔值。当全部加载并运行时,将boolean更改为true。同样的效果,但精度可能略有下降。你需要多近?

最新更新