临界区
- 一段代码内如果存在对共享资源的多线程多写操作,称这段代码为临界区。
竞态条件
- 多个线程在临界区内执行,由于大吗的执行序列不同导致结果无法预测,称之为发生竞态条件
i++(i是静态变量)执行时的JVM字节码指令
在JAVA内存模型中,完成静态变量的自增、自减操作需要在主存和工作内存进行数据交换。
- 主内存:所有线程共享,主要包括方法区和堆
- 工作内存:线程私有,主要包括线程私有的栈和对主存部分变量拷贝的寄存器(包括程序计数器PC和CPU工作的高速缓存区)
1. getstatic i//获取静态变量i的值
2. iconst_1 //准备常量1
3. iadd //i+1
4. putstatic i//将修改后的值存入静态变量i

@Slf4j(topic = "ants.UnSafeCount")
public class UnSafeCount {
static int count = 0 ;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread("t1") {
@SneakyThrows
@Override
public void run() {
for (int i=0;i<5000;i++){
count--;
}
}
};
Thread t2 = new Thread("t2") {
@SneakyThrows
@Override
public void run() {
for (int i=0;i<5000;i++){
count++;
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("count值为:{}",count);
}
}
synchronized
- 阻塞式
- 采用互斥方式,保证同一时刻至多只有一个线程持有【对象锁】
- 其他线程获取【对象锁】时阻塞
- 拥有【对象锁】的线程可以安全的执行临界区的代码
- 同步和互斥否可采用synchrinized
互斥:保证临界区的竞态条件发生,同一时刻只能有一个线程执行临界区代码
同步 :线程执行的先后,顺序不同,需要一个线程等待其他线程运行到某个点
@Slf4j(topic = "ants.SafeCountSync")
public class SafeCountSync {
// 使用synchronized,操作变成线程安全,此时输出值为0
static int count = 0;
static Object obj = new Object();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread("t1") {
@SneakyThrows
@Override
public void run() {
for (int i = 0; i < 5000; i++) {
synchronized (obj) {
count--;
}
}
}
};
Thread t2 = new Thread("t2") {
@SneakyThrows
@Override
public void run() {
for (int i = 0; i < 5000; i++) {
synchronized (obj) {
count++;
}
}
}
};
t1.start();
t2.start();
t1.join();
t2.join();
log.debug("count值为:{}", count);
}
}

小结:
- synchronized实际上是用对象锁保证了临界区代码的原子性,临界区内的代码对外是不可分割的,不会被线程切换所打断。
synchronized修改
- 修饰实例方法和静态方法
- 修饰实例代码块和静态代码块
变量的线程安全分析
成员变量和静态变量线程安全
- 如果没有被共享,则线程安全
- 如果被共享了,根据变量的状态是否改变,分为
- 如果只有读操作,则线程安全
- 如果涉及读写操作,则这段代码是临界区,需要考虑线程安全
局部变量线程安全
- 局部变量是线程安全的
- 局部变量引用的对象则未必是线程安全的
- 如果引用对象没有逃离方法的作用范围,则线程安全
- 如果引用对象逃离方法的作用范围,则线程不安全
线程安全类
多个线程调用他们同一个实例的某个方法是线程安全的,但是组合调用不一定安全
- String(内部属性不能修改,线程安全)
- Integer、Long等包装类(内部属性不能修改,线程安全)
- StringBuffer
- Vector、Hashtable
- JUC
- Random
网友评论