并发总结

484 阅读4分钟

一.ReentrantLock

ReentrantLock是一种基于AQS框架的应用实现,是JDK中的一种线程并发访问的同步手段,它的功能类似于synchronized是一种互斥锁,可以保证线程安全。而且它具有比synchronized更多的特性,比如它支持手动加锁与解锁,支持加锁的公平性

模板模式-子类根据需要做具体业务实现

1、FairSync 公平锁的实现

2、NonfairSync 非公平锁的实现

3.涉及到的场景

1.阻塞等待队列           
2.独占
3.公平/非公平
4.可重入
5.允许中断

4.常用的方法

外部方法
 1.lock.lock();                        //尝试获取锁,线程中断不抛异常
 2.lock.unlock();                      //尝试释放锁
 3.lockInterruptibly                   //尝试获取锁,线程中断抛异常
内部方法
 1.LockSupport.park(this);             //阻塞线程
 2.LockSupport.unpark(s.thread);       //释放线程
 3.Thread.interrupted();               //消除线程中断记录
 4.Thread.currentThread().interrupt(); //线程中断
 5.tryAcquire(int)                     //独占方式。尝试获取资源,成功则返回true,失败则返回false
 6.tryRelease(int)                     //独占方式。尝试释放资源,成功则返回true,失败则返回false

二.Semaphore

Semaphore 字面意思是信号量的意思,它的作用是控制访问特定资源的线程数目,底层依赖AQS的状态State,是在生产当中比较常用的一个工具类

1、FairSync 公平锁的实现

2、NonfairSync 非公平锁的实现

需求场景 资源访问,服务限流(Hystrix里限流就有基于信号量方式)。

    1.阻塞等待队列
    2.共享
    3.公平/非公平
    

常用方法

外部方法
  1.publicSemaphore(int permits)                //构造方法:permits表示每次允许进入的线程数量
  2.publicSemaphore(int permits,boolean fair)   //构造方法:permits表示每次允许进入的线程数量,air表示公平性
  3.acquire()                                   //表示阻塞并获取许可
  4.release()                                   //表示释放许可

内部方法

  1.LockSupport.park(this);               //阻塞线程
  2.LockSupport.unpark(s.thread);         //释放线程
  3.Thread.interrupted();                 //消除线程中断记录
  4.Thread.currentThread().interrupt();   //线程中断
  5.tryAcquireShared(arg)                 //共享方式。尝试获取资源,成功则返回true,失败则返回false
  6.tryReleaseShared(arg)                 //共享方式。尝试释放资源,成功则返回true,失败则返回false

三.CountDownLatch

CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch应用场景例子

比如陪媳妇去看病。医院里边排队的人很多,如果一个人的话,要先看大夫,看完大夫再去排队交钱取药。现在我们是双核,可以同时做这两个事(多线程)。

假设看大夫花3秒钟,排队交费取药花5秒钟。我们同时搞的话,5秒钟我们就能完成,然后一起回家(回到主线程)

四.Atomic

在Atomic包里一共有12个类,四种原子更新方式,分别是原子更新基本类型,原子更新数组,原子更新引用和原子更新字段。Atomic包里的类基本都是使用Unsafe实现的包装类

原理

基于CAS机制来做原子更新

五.Unsafe

Unsafe是位于sun.misc包下的一个类,主要提供一些用于执行低级别、不安全操作的方法,如直接访问系统内存资源、自主管理内存资源等,这些方法在提升Java运行效率、增强Java语言底层资源操作能力方面起到了很大的作用。但由于Unsafe类使Java语言拥有了类似C语言指针一样操作内存空间的能力,这无疑也增加了程序发生相关指针问题的风险。在程序中过度、不正确使用Unsafe类会使得程序出错的概率变大,使得Java这种安全的语言变得不再“安全”,因此对Unsafe的使用一定要慎重

Unsafe类为一单例实现,提供静态方法getUnsafe获取Unsafe实例,当且仅当调用getUnsafe方法的类为引导类加载器所加载时才合法,否则抛出SecurityException异常。

通过反射获取单例对象theUnsafe

public class UnsafeInstance {public static Unsafe reflectGetUnsafe() {
 
  try {
        Field field =Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(truereturn (Unsafe) field.get(null);                                       
         } catch (Exception e) {
         e.printStackTrace();       
        }return null;   
     }}
   

Unsafe功能介绍

Unsafe提供的API大致可分为内存操作、CAS、Class相关、对象操作、线程调度、系统信息获取、内存屏障、数组操作等几类,下面将对其相关方法和应用场景进行详细介绍