Java 线程:竞争条件与同步
Java thread: Race condition vs synchronization
即使调用代码块已同步,竞争条件也会发生。再想想,这似乎是一个锁的问题。请查看以下简单代码块(代码会更好地解释它)-
class CriticalSectionTest {
public void initWithSync() {
final CriticalSection cSection = new CriticalSection();
Thread threadA = new Thread(new Runnable() {
@Override public void run() {
synchronized (cSection) {
cSection.add(2);
System.out.println(
"Value after adding from thread-A: " + cSection.getCount());
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override public void run() {
synchronized (cSection) {
cSection.add(3);
System.out.println(
"Value after adding from thread-B: " + cSection.getCount());
}
}
});
threadA.start();
threadB.start();
//Desired output:
//A: 2
//B: 5
}
}
class CriticalSection {
private long count = 0;
public void add(long value) {
/* This method was not made synchronized, intentionally as its done in caller class
*/
this.count = this.count + value;
}
public long getCount() {
return count;
}
}
在多次运行中,它会打印以下输出 -
不行
Value after adding from thread-B: 3
Value after adding from thread-A: 5
看起来不错
Value after adding from thread-A: 2
Value after adding from thread-B: 5
有什么解释吗?还是我缺少一些基础知识?
每个线程的开始顺序没有什么是安全的。 Main
线程将一个接一个地启动线程,但不会阻止以下情况:
THREAD A : START
THREAD B : START
THREAD A : WAIT
THREAD B : RUN
THREAD A : RUN
THREAD A : STOP
THREAD B : STOP
threadB
有时可以在 threadA
之前开始治疗,这就是您现在面临的情况。
同步不决定执行顺序。它只是保证线程不会同时执行代码。
调用Thread.start()
不会立即调用Thread.run()
;它只是要求线程调度程序在将来的某个时候 运行 它。对您描述的行为的解释是,线程调度程序有时可能会在线程 A 之前开始执行线程 B。这是预期的行为。
如果您希望代码按特定顺序和顺序执行,在单个线程中完成所有操作要容易得多。
即使调用代码块已同步,竞争条件也会发生。再想想,这似乎是一个锁的问题。请查看以下简单代码块(代码会更好地解释它)-
class CriticalSectionTest {
public void initWithSync() {
final CriticalSection cSection = new CriticalSection();
Thread threadA = new Thread(new Runnable() {
@Override public void run() {
synchronized (cSection) {
cSection.add(2);
System.out.println(
"Value after adding from thread-A: " + cSection.getCount());
}
}
});
Thread threadB = new Thread(new Runnable() {
@Override public void run() {
synchronized (cSection) {
cSection.add(3);
System.out.println(
"Value after adding from thread-B: " + cSection.getCount());
}
}
});
threadA.start();
threadB.start();
//Desired output:
//A: 2
//B: 5
}
}
class CriticalSection {
private long count = 0;
public void add(long value) {
/* This method was not made synchronized, intentionally as its done in caller class
*/
this.count = this.count + value;
}
public long getCount() {
return count;
}
}
在多次运行中,它会打印以下输出 -
不行
Value after adding from thread-B: 3
Value after adding from thread-A: 5
看起来不错
Value after adding from thread-A: 2
Value after adding from thread-B: 5
有什么解释吗?还是我缺少一些基础知识?
每个线程的开始顺序没有什么是安全的。 Main
线程将一个接一个地启动线程,但不会阻止以下情况:
THREAD A : START
THREAD B : START
THREAD A : WAIT
THREAD B : RUN
THREAD A : RUN
THREAD A : STOP
THREAD B : STOP
threadB
有时可以在 threadA
之前开始治疗,这就是您现在面临的情况。
同步不决定执行顺序。它只是保证线程不会同时执行代码。
调用Thread.start()
不会立即调用Thread.run()
;它只是要求线程调度程序在将来的某个时候 运行 它。对您描述的行为的解释是,线程调度程序有时可能会在线程 A 之前开始执行线程 B。这是预期的行为。
如果您希望代码按特定顺序和顺序执行,在单个线程中完成所有操作要容易得多。