嗨,我是并发编程领域的新手,我正在测试下面的代码,并且was循环似乎没有终止线程。有人能帮我解释一下这里发生了什么吗。
public class PrimePrinter{
public long counter = 0;
public synchronized long getCounter() {
return counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while (counter < 100) {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " +getCounter());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for(int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}最后几行输出
Thread-4 : 81
Thread-5 : 87
Thread-7 : 91
Thread-5 : 97
Thread-2 : 95
Thread-4 : 98
Thread-6 : 96
Thread-8 : 90
Thread-1 : 93
Thread-3 : 92
Thread-0 : 94
Thread-2 : 99
Thread-6 : 107
Thread-3 : 103
Thread-0 : 104
Thread-1 : 105
Thread-8 : 106
Thread-5 : 102
Thread-4 : 101
Thread-7 : 100发布于 2019-01-03 10:35:33
每个线程在测试该counter < 100之后等待一秒钟,在这一秒内,其他线程可以增加计数器。
更新:您可以这样做:
while (true) {
long current = getCounter();
if (current >= 100) {
break;
}
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " : " + current);
} catch (InterruptedException e) {
e.printStackTrace();
}
}发布于 2019-01-03 10:49:08
这并不是因为一个不可错过的关键原因。考虑一下代码实际运行的方式。它检查计数器值,然后休眠,然后打印,然后递增。
您有9个线程一次运行。然后,其中8个线程检查该值,此时,该值小于100。所以他们通过了测试继续前进。所有8人然后睡觉1000毫秒。同时,您的另一个线程刚刚增加了值.还有8人即将从睡梦中醒来。
因此,如果您的值是99 (这是不可避免的),那么您现在将从刚刚递增的线程中得到一个100的值。然后,已经通过测试的8也将递增,从而使计数器的结果值为108。
但是,要运行的最后一个线程将显示值107,因为您将打印所有运行的增量。
如果您以相反的方式这样做(如下面的代码所示),您将不会遇到这个问题。
以下代码工作正常:
public class PrimePrinter {
public long counter = 0;
public synchronized long getCounter() {
return counter;
}
public synchronized void incrementCounter() {
counter++;
}
public Thread makeThread() {
Runnable rn = new Runnable() {
/*
* (non-Javadoc)
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
while (getCounter() < 100) {
try {
incrementCounter();
System.out.println(Thread.currentThread().getName()
+ " : " + getCounter());
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
return new Thread(rn);
}
public static void main(String[] args) {
int n = 10;
Thread[] threads = new Thread[10];
PrimePrinter pp = new PrimePrinter();
for (int i = 1; i < n; i++) {
threads[i] = pp.makeThread();
threads[i].start();
}
}
}https://stackoverflow.com/questions/54020445
复制相似问题