1. 共享代来的问题(操作统一资源)
两个线程对初始值为 0 的静态变量一个做自增,一个做自减,各做 5000 次,结果是 0 吗?
代码:
import lombok.extern.slf4j.Slf4j;
@Slf4j(topic = "c.Test17")
public class Test17 {
static int counter = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter++;
}
}, "t1");
Thread t2 = new Thread(() -> {
for (int i = 0; i < 5000; i++) {
counter--;
}
}, "t2");
t1.start();
t2.start();
t1.join();
t2.join();
log.debug(": {}", counter);
}
}
运行结果:
问题分析:
以上的结果可能是正数、负数、零。为什么呢?因为 Java 中对静态变量的自增,自减并不是原子操作,要彻底理解,必须从字节码来进行分析
正确的执行顺序:
出现负数的情况:
出现正数的情况:
2. 临界区 Critical Section
例如,下面代码中的临界区:
static int counter = 0;
static void increment()
{
counter++; }
static void decrement()
{
counter--; }
3. 竞态条件 Race Condition
多个线程在临界区内执行,由于代码的执行序列不同而导致结果无法预测,称之为发生了竞态条件
|