Java多线程查询



嗨,我是并发编程领域的新手,我正在测试下面的代码,看起来while循环并没有为线程终止。有人能解释一下这里发生了什么吗。

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

这不起作用的一个重要原因是不要错过。请考虑代码的实际运行方式。它检查计数器值,然后休眠,然后打印then增量。

您有9个线程同时运行。然后,其中8个线程检查该值,此时该值小于100。所以他们通过了测试并继续前进。然后8个人都睡1000毫秒。同时,您的另一个线程刚刚增加了值。。。还有8个人即将从睡梦中醒来。

因此,如果您的值是99(这是不可避免的),那么您现在将从刚刚递增的线程中获得一个值100。然后,那些已经通过测试的8个也将递增,给计数器一个108的结果值。

但是,最后一个运行的线程将显示值107,因为您为所有运行打印THEN增量。

如果你用另一种方法(比如下面的代码),你就不会遇到这个问题。

以下代码工作正常:

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();
}
}
}

每个线程在测试该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();
}                   
}

最新更新