多线程高并发编程(2) -- 可重入锁介绍和自定义

什么是 “可重入”?可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。即可重入锁的作用就是为了避免死锁,java中synchronized和ReentrantLock都是可重入锁。

  //synchronized 可重入锁    
private void test() 
{        
//  第一次获得锁        
synchronized (this) 
{            
while (true) 
{                
//  第二次获得同样的锁                synchronized (this) 
{                    System.out.println("ReentrantLock!");                }                
try
 {                    
Thread.sleep(1000);                
} 
catch (InterruptedException e) 
{                    
e.printStackTrace();                
}            
}        
}    
}  
//ReentrantLock可重入锁    
Lock lock = new ReentrantLock();    
private void test1() 
{        
lock.lock();        
try 
{            
test2();        
} 
finally 
{            
lock.unlock();        
}
    }    
private void test2() 
{        
lock.lock();        
try 
{            System.out.println("ReentrantLock!");        
} 
finally 
{            
lock.unlock();        
}    
}

一.自定义不可重入锁

所谓不可重入锁,即若当前线程执行某个方法已经获取了该锁,那么在方法中尝试再次获取锁时,就会获取不到被阻塞。下面的线程执行test1()方法首先获取lock,接下来执行test2()方法就无法执行test2()中的逻辑,必须先释放锁。

// 不可重入锁class Lock 
{    
//是否占用    
private boolean isLocked = false;    
//使用锁    
public synchronized void lock() 
{        
while (isLocked) 
{
//已经占用            
try {                
this.wait();
//等待            
} 
catch (InterruptedException e) 
{                
e.printStackTrace();            
}        
}        
isLocked = true;//修改标识为已经占用    
}    
//释放锁    
public synchronized void unLock() 
{        
isLocked = false;
//修改标识为未占用        
notify();
//唤醒等待线程    
}
}
============使用===========    
Lock lock = new Lock();    
public void test1() 
{        
lock.lock();        
test2();        
lock.unLock();    
}    
private void test2() 
{        
lock.lock();       
 //...        
lock.unLock();    
}

二.自定义可重入锁

流程:

  1. 定义锁占用标识、存储线程、线程锁持有数量;
  2. 使用锁:判断是否已经占用和当前线程是否不等于存储线程,如果条件符合进入等待,不符合则修改占用标识、存储线程为当前线程、线程锁数量+1;在此我向大家推荐一个架构学习交流圈。交流学习指导伪鑫:1253431195(里面有大量的面试题及答案)里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多
  3. 释放锁:判断当前线程是否等于存储线程,条件符合则线程锁数量-1,当线程锁数量=0时,修改占用标识,唤醒等待线程,将存储线程置为null;
    // 可重入锁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;
    }
    }
    使用=
    public class LockTest
    {
    ReLock lock = new ReLock();
    public void test1() throws InterruptedException
    {
    lock.lock(); System.out.println(lock.getHoldCount()); test2();
    lock.unlock(); System.out.println(lock.getHoldCount());
    }
    //可重入
    public void test2() throws InterruptedException
    {
    lock.lock(); System.out.println(lock.getHoldCount());
    //…
    lock.unlock(); System.out.println(lock.getHoldCount());
    }
    public static void main(String[] args) throws InterruptedException
    {
    LockTest lockTest= new LockTest(); lockTest.test1(); Thread.sleep(1000); System.out.println(lockTest.lock.getHoldCount());
    }
    }

你可能感兴趣的:(java,spring,开发语言,分布式,架构)