美文网首页
线程安全

线程安全

作者: 沐雨晨风_a924 | 来源:发表于2018-05-29 15:39 被阅读0次
线程安全主要体现在三个方面:原子性,可见性,有序性。

原子性:提供了互斥访问,同一时刻只能有一个线程对它进行操作。

可见性:一个线程对主内存的修改可以及时的被其他线程观察到。

有序性:一个线程观察其他线程的指令执行顺序,由于指令重排序的存在,该观察结果一般杂乱无序。

  • 1 原子性:
    • 1.1 AtomicXXX:
    • 1.2 锁 synchronized和Lock
  • 2 可见性:
    • 2.1 synchronized
    • 2.2 volatile
  • 3 有序性:
    • 3.1 volatile、synchronized、Lock

1.原子性

1.1AtomicXXX:

AtomicInteger,AtomicLong,LongAdder,AtomicReference,AtomicReferenceFieldUpdater,AtomicBoolean
使用AtomicStampReference解决CAS的ABA问题

CAS底层源码:

CAS原理就是拿当前的值和底层的值做对比,如果期望的值和底层的值相同,则进行相加操作,否则再重新拿值重新比较直到成功为止。

 public final int getAndAddInt(Object var1, long var2, int var4) {
        int var5;
        do {
            var5 = this.getIntVolatile(var1, var2);
        } while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

        return var5;
    }
1.2锁

synchronized:依赖JVM
修饰代码块:大括号括起来的代码,作用于调用对象
修饰方法:整个方法,作用于调用的对象
修饰静态方法:整个静态方法,作用于所有对象
修饰类:括号括起来的部分,作用于所有对象
Lock:依赖特殊的cpu指令,代码实现,ReentrantLock。

原则性对比:

synchronized:不可中断锁,适合竞争不激烈,可读性好。
Lock:可中断锁,多样化同步,竞争激烈也可维持常态。
Aomic:竞争激烈也可维持常态,比Lock性能好,但只能同步一个值。

2.可见性:

导致共享变量在线程间不可见的原因:

1.线程交叉执行
2.重排序结合线程交叉排序
3.共享变量更新后的值没有在工作内存与主存间及时更新

2.1可见性synchronized

JMM规定关于synchronized的两条规定:

1.线程解锁前,必须把共享变量的最新值刷新到主存中
2.线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存重新读取最新的值(注意,加锁解锁是同一把锁)

2.2可见性volatile

通过加入内存屏障和禁止重排序优化来实现的

1.对于volatile变量写操作时,会在写操作后加入一条store屏障指令,将本地内存中的共享变量刷新到主内存中
2.对于volatile变量读操作时,会在读操作前加入一条load屏障指令,从主内存中读取共享变量

volatile特别适合状态标记量。volatile使用如下:

volatile boolean inited = false;
//线程1
context = loadContext();
inited = true;
//线程2
while(!inited){
  sleep();
}
doSomethingWithConfig(context);

3.有序性:

java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性。
volatile、synchronized、Lock(synchronized、Lock保证每个时刻有一个线程执行同步代码,相当是让线程顺序执行同步代码,自燃保证了有序性)

4.多线程安全性总结:

原子性:Atomic包、CAS算法、synchronized、Lock
可见性:synchronized、volatile
有序性:happens-before

相关文章

  • atomic & nonatomic

    什么是线程安全??? 线程安全:多线程操作共享数据不会出现想不到的结果就是线程安全的,否则,是线程不安全的。 at...

  • ConcurrentHashMap源码设计分析

    二、线程安全(Thread-safe)的集合对象:● Vector 线程安全● HashTable 线程安全● S...

  • HashMap 和 Hashtable 的区别

    线程安全: HashMap 是非线程安全的,而 Hashtable 是线程安全的,因为 Hashtable 内部的...

  • Java 的 StringBuffer 和 StringBuil

    区别就是:线程安全,StringBuffer 是线程安全的,StringBuilder 不是线程安全的。 他俩的实...

  • Java单例模式,线程安全

    懒汉式:线程安全,开销大 双重检查锁:线程安全,根据需求使用 静态内部类锁:线程安全,比较推荐 饿汗式:线程安全,...

  • 2018-06-12 第三十七天

    一、线程安全 线程安全的问题,是针对多线程的程序。单线程的情况下,是不存在线程安全问题。 产生线程安全问题的原因:...

  • 线程安全知多少

    1. 如何定义线程安全 线程安全,拆开来看: 线程:指多线程的应用场景下。 安全:指数据安全。 多线程就不用过多介...

  • JAVA 线程安全

    线程安全定义 一个类在可以被多个线程安全调用时就是线程安全的。 线程安全分类 线程安全不是一个非真即假的命题,可以...

  • synchronized锁

    一、线程安全的概念与synchronized 1、线程安全概念 并发程序开发的一大关注重点就是线程安全,线程安全就...

  • 线程安全的NSMutableDictionary

    NSDictionary是线程安全的,NSMutableDictionary是线程不安全的。利用锁来保证线程的安全...

网友评论

      本文标题:线程安全

      本文链接:https://www.haomeiwen.com/subject/knlajftx.html