1.volatile关键字
volatile是jvm的轻量级的同步锁
- 保证可见性
- 不保证原子性
- 禁止指令重排
2. JMM(内存模型)
- 可见
- 原子
- 有序
上边三个代表的是三个不同的线程,下边代表的是主内存。所有的变量都存在主内存上,每个线程都有自己的工作内存,当线程用到变量的时候,就去主内存复制一份,如果需要修改,则在自己的内存空间修改,修改完了更新到主内,主内存会通知所有复制过这个变量的线程。这就是可见性的体现。
3.CAS
compare and set 比较并交换,这个在JUC里边被大量的使用。
cas能够保证i++在多线程中不出问题,用的就是unsafe类,unsafe类调用底层,根据内存偏移量来获取值。
cas是cpu的一条原语指令,不会造成所谓的数据不一致的问题。
cas4de源码是一个do while ,先去主内存里边拿到值,如果和期望值(之前拿到的)不一样,就不停地去主内存拿值,并且替换掉自己原来的期望值。
cas缺点:它能够保证安全,是因为自己的在不同的占用cpu,如果有很多个线程,就可能有一直在执行这个操作。
它只能保证一个共享变量的原子性。
ABA的问题。
4.ABA问题
CAS引发的ABA问题是这样产生的,线程A和B都去主内存拷贝一个数据,A线程要执行更长的时间,B要执行很短的时间,恰好的是,B线程先把数据改了一次,最终又改回来了,但是A过来比较的时候以为没有改变过,这就是ABA问题。
ABA的问题解决就是加上版本号(类似于时间戳)。
5.集合类在多线程下的不安全问题
报错:java.util.concurrentModificationException
解决方案可以是:Collections.synchronizedList(new ArrayList<>());
可以是:ArrayList<T> lsit = new CopyOnwriteArrayList<>();