• 40 多线程(十二)——ReentrantLock 可重入锁


    我们使用的synchronized加的锁是可以延续使用的,如下:

     public void test() {
    	 //第一次获得锁
    	 synchronized(this) {
    		 while(true) {
    			 //第二次获得同样的锁
    			 synchronized(this) {
    				 System.out.println("ReentrantLock");
    			 }
    			 try {
    				 Thread.sleep(1000);
    			 } catch (InterruptedException e) {
    				 // TODO Auto-generated catch block
    				 e.printStackTrace();
    			 }
    		 }
    	 }
     }
    

      

    使用synchronized加的锁必须等到线程结束才会被释放,这可能会造成死锁。

    而相对synchronized,ReentrantLock锁更灵活,它可以指定加锁一段时间后主动释放锁等更为强大的功能,目前仅做了解即可。

    详细内容自行百度。接下来仿写ReentrantLock源码,实现基本的lock与unLock方法。

    package _20191209;
    /**
     * 可重入锁演示:锁不以延续使用
     * @author TEDU
     *
     */
    public class LockTest03 {
    	ReLock lock = new ReLock();
    	public void a() throws InterruptedException {
    		lock.lock();
    		System.out.println(lock.getHoldCount());
    		doSomething();//需要被加锁的部分
    		lock.unlock();
    		System.out.println(lock.getHoldCount());
     }
    	
     public void doSomething() throws InterruptedException {
    	 lock.lock();
    	 System.out.println(lock.getHoldCount());
    	 //。。。。。。
    	 lock.unlock();
    	 System.out.println(lock.getHoldCount());
     }
     
    	public static void main(String[] args) throws InterruptedException {
    		LockTest03 test = new LockTest03();
    		test.a();
    	}
     
    }
    //可重入锁
    class ReLock{
    	//是否被占用
    	private boolean isLocked = false;
    	//存储线程的变量
    	private Thread lockedBy = null;
    	//锁计数器:锁使用次数
    	private int holdCount = 0;
    	//使用锁
    	public synchronized void lock() throws InterruptedException{
    		Thread t = Thread.currentThread();
    		while(isLocked && lockedBy != t) {
    			wait();
    		}
    		
    		isLocked = true;
    		lockedBy = t;
    		holdCount ++;
    	}
    	//释放锁
    	public synchronized void unlock() {
    		if(Thread.currentThread() == lockedBy) {
    			holdCount --;
    			if(holdCount == 0) {
    				isLocked = false;
    				notify();
    				lockedBy = null;
    			}
    		}
    	}
    	public int getHoldCount() {
    		return holdCount;
    	}
    }
    

      

    如果需要使用ReentrantLock只需要new一个就行了:

    ReentrantLock relock = new ReentrantLock();
    relock.lock();//加锁
    relock.unlock();//解锁
    

      

  • 相关阅读:
    同步与异步接口
    教你用 WEB SPEECH API 和 node.js 创建 一个简单的AI
    face ++ 人脸识别技术初步
    php ddos 安全处理代码
    基于GBT28181:SIP协议组件开发-----------第五篇SIP注册流程eXosip2实现(二)
    基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)
    基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现
    基于GBT28181:SIP协议组件开发-----------第二篇SIP组件开发原理
    基于GBT28181:SIP协议组件开发-----------第一篇环境搭建
    qt二维码示例
  • 原文地址:https://www.cnblogs.com/Scorpicat/p/12012539.html
Copyright © 2020-2023  润新知