java线程并发带来的问题与解决方案

一、为什么会发生多线程并发问题?

并发问题的根本原因是操作了共享资源,比如一个统计网站访问量的功能,每个用户进来就需要对访问量加1,如果做不好,那么就会导致统计的数字不准确

二、在并发编程中,我们通常会遇到以下三个问题:原子性问题,可见性问题,有序性问题。

三、具体的解决方案有哪些?

1、ThreadLocal:ThreadLocal本质上是每个线程有自己的一个副本,每个线程的副本是互不影响,没有任何关系的。

2、CAS原子类:CAS的意思是Compare And Swap,就是比较并替换的意思,CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B,只有当内存地址V所对应的值和旧的预期值A相等的时候,才会将内存地址V对应的值更新为新的值B。Java中,Atomic系列使用的是一种无锁化的CAS操作,是基于乐观锁的,它的并发性能比较高,可以多个线程同时执行,并且保证不会出现线程安全问题。

java线程并发带来的问题与解决方案

3、volatile关键字

volatile关键字可以保证可见性和禁止指令重排序,它确保指令重排序时不会把其后面的指令排到内存屏障之前的位置,也不会把前面的指令排到内存屏障的后面;即在执行到内存屏障这句指令时,在它前面的操作已经全部完成;它会强制将对缓存的修改操作立即写入主存;如果是写操作,它会导致其他CPU中对应的缓存行无效。

volatile使用的场景:从上面看,其实volatile关键字使用的场景比较少,比如像状态开关,双重检查。

4、synchronized关键字

4.1、synchronized的三种使用方法:

修饰实例方法、修饰静态方法、修饰代码块

5、Lock相关类

java线程并发带来的问题与解决方案

Lock和synchronized有以下几点不同:

  1)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;

  2)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;

  3)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;

  4)通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。

  5)Lock可以提高多个线程进行读操作的效率。

 

上一篇:数据结构(三)栈


下一篇:栈、链表等初始化的思考