Java 为什么线程不能正常工作?
以下是我的代码:Java 为什么线程不能正常工作?,java,multithreading,Java,Multithreading,以下是我的代码: class Test { private int x = 0; public void incX() { synchronized(this) { ++x; } System.out.println("x is: "+x+" "+Thread.currentThread().getName()); } public static void main(String[] args)
class Test {
private int x = 0;
public void incX() {
synchronized(this) {
++x;
}
System.out.println("x is: "+x+" "+Thread.currentThread().getName());
}
public static void main(String[] args) {
Test test = new Test();
Thread t1 = new Thread(() -> {
test.incX();
});
Thread t2 = new Thread(() -> {
test.incX();
});
t1.start();
t2.start();
System.out.println("Done");
}
}
以下是我的输出:
x is: 2 Thread-1
x is: 1 Thread-0
这里线程t2
输出2,但是线程t1
也应该输出2,对吗?当x
等于2时,它应该对线程t1
可见,对吗?那么为什么线程t1
是1呢
线程
t2
如何输出2,然后线程t1
输出1?由于线程t2
已经输出2,那么x的值应该是2。那么线程t1
怎么还能输出1呢?我误解了吗?您的整个系统.out.println
行离原子线很远。例如,在构造字符串和调用
System.out.println
之间,可能会发生很多事情
让我们考虑一个等价的代码块:
public void incX() {
synchronized(this) {
++x;
}
String implicit = "x is: " + x + " " + Thread.currentThread().getName();
// <-- "Point X"
System.out.println(implicit);
}
首先,您的代码没有正确同步。你的表情
"x is: "+x+" "+Thread.currentThread().getName()
在不同步的情况下读取共享变量x
的值,即在数据竞争中。但是,它至少会看到前面的synchronized
块观察到的值
现在让我们考虑一下程序的可能输出。线程一步一步地进行,所有线程的步骤都是交错的。考虑以下顺序:
Thread-0
进入synchronized
块,读取x==0
,将其更新为1
,然后离开该块。随后的字符串表达式读取该值1
Thread-1
进入synchronized
块,读取x==1
,将其更新为2
,然后离开该块。随后的字符串表达式读取该值2
Thread-1
进入synchronized
方法println
并输出其结果2
Thread-0
进入synchronized
方法println
并输出其结果1。
你可能误解了。@duffymo:你能解释一下我误解了什么吗?其他人做得更好。我没有什么要补充的,只是说,当代码无法满足您的期望时,最好检查您的假设。
"x is: "+x+" "+Thread.currentThread().getName()