目录
今天我们就围绕这个代码 去理解一下什么是线程安全!
- class Counter {
- public int counter = 0;
-
- public void increase() {
- this.counter++;
- }
- }
-
- public class demo1 {
- public static void main(String[] args) throws InterruptedException {
- Counter count = new Counter();
- Thread thread1 = new Thread(() -> {
- for (int i = 0; i < 5000; i++) {
- count.increase();
- }
- });
- Thread thread2 = new Thread(() -> {
- for (int i = 0; i < 5000; i++) {
- count.increase();
- }
- });
- thread1.start();
- thread2.start();
- thread1.join();
- thread2.join();
- System.out.println(count.counter);
- }
- }
-
- 代码的执行结果 是随机的 并不是10000
我们可以看上述的代码 我们想让counter通过两个线程同时对counter进行++,但是运算结果却跟我们的预期不符,这就是线程不安全的结果。

①抢占式执行
线程不安全的万恶之源,也要注意并不是完全随机,但在应用层程序中是没有规律的
②修改的操作不是原子的
比如修改的n变量,不是原子的,修改的时候有可能读取到的n是脏数据
③内存可见性问题
这个是JVM代码优化而带来的问题,在逻辑等效的情况下编译器会自动优化代码!
④指令序重排
使用锁 synchronized
我们可以对一个对象进行加锁,让其线程安全!比如下面对上述countrer的加锁优化
- class Counter {
- public int counter = 0;
- public synchronized void increase() {//这里就相当于加锁
- this.counter++;
- }
- }
- 这样线程在调用synchronized关键字修饰的increase方法的时候 就不会发生线程的不安全

- class Counter {
- public int counter = 0;
- public synchronized void increase() {//对increase这个方法加锁
- this.counter++;
- }
- }
- class Counter {
- public int counter = 0;
- public void increase() {
- synchronized(this){//谁调用的increase方法,这个this就代表谁
- this.counter++;//对这个只有一句的代码块进行加锁
- }
- }
- }