我正在尝试执行5个线程同时完美启动。但是考虑下面的输出,我认为它们是在同一时间开始但不是同时开始,因为年龄计数器总是以5计数结束。如果他们真正同时执行了 群体的年龄输出必须相同。真正的同时或完美同时我认为所有5个线程传递1作为年龄和所有线程打印相同的年龄而不是增量值。请纠正我。
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** ...
答案 0 :(得分:1)
所有线程使用相同计数器的原因是您正在为它们提供相同的Runnable
实例。只需为循环内的每个线程创建一个新的:
for (int i = 0; i < 10; i++) {
Runnable worker = new MyRunnable(1);
executorService.execute(worker);
}
答案 1 :(得分:0)
它可能不太理想,但如果你需要它们完全对齐,我会设置某种类型的Mark。使用System.nanoTime()将当前时间缩短到纳秒。给它一段时间等待,比如一秒钟(1_000_000_000)纳秒。确保延迟足够长(无论是什么),以便初始化所有线程并进入等待点。将MarkTime传递给创建时的每个线程。然后让每个线程都有这样的函数:
while(System.nanoTime() < MarkTime){
// do nothing
}
Boom,当达到时间时,所有线程都关闭并运行,协调到纳秒级。
就像跑步者在比赛的起跑线上做好准备一样。他们都在不同的时间到达了这条线,但都是从同一个先发手枪射击开始的。
另外,正如@Keppil所说,你可能想为每个版本创建一个新的线程实例,而不是同一个实例的5个副本。这样你可以确定它们是独立运行的,但同时也是如此。
或者:另一种方法是在父类中设置一个布尔值,将其设置为false,在所有线程都处于活动状态后,让它们检查该布尔值。当所有加载并运行时,将boolean更改为true。效果相同,但精度可能略有下降。你有多接近它?