我有一个简单的代码片段,并尝试尝试一下,但在接下来的代码中,我不清楚输出数据的顺序:
public class Main {
static int n = 100;
public static synchronized int decreaseValue(){
return --n;
}
public static void main(String[] args) throws InterruptedException, IOException {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
System.out.println("Thread1: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"Thread1");
t1.start();
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
System.out.println("Thread2: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},"Thread2");
t2.start();
while(true){
try {
System.out.println("Main Thread: "+ decreaseValue());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}我不明白,为什么我会按下一个顺序得到这样的值:
Thread1: 89 Thread2: 90主线程: 88
请注意N值,而不是调用线程的顺序:
Thread1: 99
Thread2: 98
Main Thread: 97
Main Thread: 95
Thread2: 94
Thread1: 96
Main Thread: 92发布于 2012-10-28 20:47:41
您一定在某处读到过必须使用synchronized来确保正确的排序,或者类似的东西。“排序”这个词与您脑海中的概念不同:它意味着同步块的执行总是有一些明确的顺序。排序是事先不知道的,但每次都会知道。如果没有同步,您甚至得不到这种保证:一个线程可以感知一个顺序,另一个线程可以感知不同的顺序,或者根本不感知其他线程的任何操作。
关于您的编辑:
如果您担心打印输出顺序混乱,这是因为您的println语句在synchronized之外,因此可以独立于对decreaseValue的调用进行交织。
发布于 2012-10-28 20:41:50
线程并行运行。你不能预测他们的执行顺序。您可以设置线程优先级,确定其执行顺序的优先级。
发布于 2012-10-28 20:37:20
这些线程是并发运行的,并且没有任何东西对它们应该调用您的decreaseValue()函数的位置进行排序。您可能希望它们是有序的,因为您正在执行相同数量的睡眠:),但是一旦线程将从睡眠中启动/恢复,CPU就会将线程放入运行队列(创建执行顺序,这是同步将保证的顺序),因此打印的顺序取决于CPU将线程放入运行队列的方式。
如果您对打印顺序有疑问,控制台上的打印也是同步的(但与decreaseValue不在同一块中)。同样的逻辑也适用于打印,就像减少值一样。
如果希望以值递减的相同顺序查看打印结果,可以在decreaseValue()函数中移动打印。但这不会影响值递减的顺序。
https://stackoverflow.com/questions/13108824
复制相似问题