我正在尝试同时完美地执行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。同样的效果,但精度可能略有下降。你需要多近?