zoukankan      html  css  js  c++  java
  • 线程同步Lock锁

    Lock接口历史

    java1.5版本之前只有synchronized一种锁,lock是java1.5版本之后提供的接口。lock接口与synchronized接口功能相同,但是需要手动获取锁和释放锁。既然提供了lock锁那必然就有一定的优点,例如:

    lock锁具有锁的可操作性,可以中断获取和超时获取锁等多种同步获取锁的优点。除此之外,lock锁还有一个非常强大的实现类重入锁和读写锁。

    Lock接口的使用

    Lock lock  = new ReentrantLock();
    lock.lock();
    try{
    //可能会出现线程安全的操作
    }finally{
    //一定在finally中释放锁
    //也不能把获取锁在try中进行,因为有可能在获取锁的时候抛出异常
      lock.ublock();
    }

    lock接口和synchronized关键字的接口的区别

    lock可以尝试非阻塞的获取锁,如果这一时刻没有被其他线程获取到,则成功获取。

    Lock接口能被中断的获取锁,获取到锁的线程能够相应中断,当获取到锁的线程被中断时,中断异常将被抛出,并释放锁。

    Lock接口可以在指定时间内获取锁,如果在有效时间内未获取到锁则返回。

    Lock接口中长用的方法

    void lock()  //获取锁

    void unlock()  //释放锁

    boolean trylock()  //尝试获取锁,如果获取失败返回false

    boolean trylcok(long time,TimeUtil util)  //在指定时间内获取锁,若获取失败则返回false

    void lockInterruptibly()  //如果当前线程未被中断则获取锁。该方法也是获取锁,与lock()不同的是,该方法在获取过程中可以被中断

    Lock中的重入锁ReetrantLock实现类

    顾名思义,重入锁就是在一条线程获取到锁之后再次获取锁,就是所谓的重入锁。讲道理synchronized也同样可以做到,不同的是该实现类有个很重到的特性,就是可以实现公平与非公平获取。

    公平获取就是线程等待时间越长的越先获取到锁,反之就是非公平获取。事实上,非公平获取要比公平获取的效率要高。

    当然该锁是排他锁,也就是说在一个线程获取锁后,其他线程进入等待列队。即同一时刻有且只能有一个线程执行。

    Lock锁中的读写锁ReetrantReadWriteLock

    与重入锁有所不同的是,读写锁在同一时刻可以有多个线程同时访问。但在写线程访问时,其他读锁和写锁都将被阻塞,进入等待列队。读写锁维护了一对儿锁,一个读锁和一个写锁。通过读写锁分离,使得程序执行效率比一般的排他锁更高。(并发性:在资料上看到的是并发性更高,在这里我觉得效率更容易理解一丢丢)

    读锁:readlock();

    写锁:writelock();

    public class Cache{
      static Map<String,Object> map = new HashMap<String,Object>();
      static ReentrantReadWriteLock  rwl = new ReentrantReadWriteLock();
      static Lock rLock = rwl.readLock();
      static Lock wLock = rwl.writeLock();
      //获取一个key对应的value
      public static final Object get(String key){
      r.lock();
      try{
       return map.get(key);
       }finally{
        r.unlock();
        }
      }
      //设置key对应的value并返回旧的value
      public static fianl Object put(String key,Object value){
      w.lock();
      try{
       return map.put(key,value);
       }final{
       w.unlock();
        }
      }
      //清空缓存
      public static fianl void clear(){
      w.lock();
      try{
         map.clear();
       } finally{
        w.unlock();
        }
      }
    }

    读写锁的锁降级

    锁降级是指写锁降级成为读锁。如果当前线程持有写锁,然后将其释放再获取读锁的过程不能称为锁降级。锁降级指的在持有写锁的时候再获取读锁,获取到读锁后释放之前写锁的过程称为锁释放。

    锁降级在某些情况下是非常必要的,主要是为了保证数据的可见性。如果当前线程不获取读锁而直接释放写锁,假设此时另外一个线程获取了写锁并修改了数据。那么当前线程无法感知该线程的数据更新。

    (没怎么看明白,用程序走几次就明白了。实践见真理)。

     

     

     

  • 相关阅读:
    转:C++ 智能指针的正确使用方式
    C/C++各个周期的学习
    转: 工作中用的C++库
    转:【软件设计】深入理解日志系统的意义
    初级爬虫第四天
    初级爬虫第三天
    初级爬虫第二天
    初级爬虫第一天
    pep8介绍
    MySQL训练营01
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/9491730.html
Copyright © 2011-2022 走看看