并发编程(四):线程安全解决方案-synchronized

2020-04-07  本文已影响0人  codeMover

临界区

竞态条件

i++(i是静态变量)执行时的JVM字节码指令

在JAVA内存模型中,完成静态变量的自增、自减操作需要在主存和工作内存进行数据交换。

1. getstatic i//获取静态变量i的值
2. iconst_1 //准备常量1
3. iadd //i+1
4. putstatic i//将修改后的值存入静态变量i
静态变量修改时数据交换.png
@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

@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);
    }
}

线程安全时序图.png

小结:

synchronized修改

变量的线程安全分析

成员变量和静态变量线程安全

局部变量线程安全

线程安全类

多个线程调用他们同一个实例的某个方法是线程安全的,但是组合调用不一定安全

上一篇 下一篇

猜你喜欢

热点阅读