我正在尝试执行5个线程开始完美的同时。但看看下面的输出,我认为它们是同时开始的,但不是同时开始的,因为年龄计数器总是以5个计数结束。如果它们并发执行real,则该簇的年龄输出必须是相同的。通过真实的、并发的或完美的相同时间,我认为所有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时,输出中有一些有趣的东西
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** ...发布于 2015-03-23 04:40:18
所有线程都使用相同的计数器的原因是您为它们提供了相同的Runnable实例。只需为循环中的每个线程创建一个新的线程:
for (int i = 0; i < 10; i++) {
Runnable worker = new MyRunnable(1);
executorService.execute(worker);
}发布于 2015-03-23 05:08:26
这可能不是很理想,但如果您需要它们完全对齐,我会设置某种类型的Mark。使用System.nanoTime()获取精确到纳秒的当前时间。给它一段时间等待,比方说一整秒(1_000_000_000)纳秒。确保延迟足够长(不管它是什么),以便所有线程初始化并到达等待点。在创建时将该MarkTime传递给每个线程。然后让每个线程都有一个这样的函数:
while(System.nanoTime() < MarkTime){
// do nothing
}当到达时间时,所有线程都关闭并运行,协调到纳秒。
就像跑步者在起跑线上为比赛做准备。他们都是在不同的时间到达终点线,但都是从同一发令枪射击开始的。
此外,正如@Keppil所说,您可能希望为每个版本创建线程的新实例,而不是同一实例的5个副本。这样,您就可以确保它们同时独立运行。
或者:另一种方法是在父类中设置一个布尔值,将其设置为false,在所有线程都处于活动状态后,让它们检查该布尔值。当所有这些都加载并运行时,将boolean更改为true。效果相同,但精确度可能会略有下降。你需要它多近?
https://stackoverflow.com/questions/29199374
复制相似问题