重入锁ReentrantLock

本文深入探讨了可重入锁的概念,重点介绍了synchronized关键字和ReentrantLock类在Java中的应用,展示了它们如何避免死锁并提供更细粒度的锁控制。

什么是可重入?

可重入锁指的是可重复可递归调用的锁,在外层使用锁之后,在内层仍然可以使用,并且不发生死锁(前提得是同一个对象或者class),这样的锁就叫做可重入锁。ReentrantLock和synchronized都是可重入锁。

一.在讲解之前先介绍一下synchronized

synchronized是java内置的关键字,获取和释放锁由JVM实现,非常方便。然而synchronized也有一定的局限性。

  1. 当线程尝试获取锁的时候,如果获取不到锁会一直阻塞。
  2. 如果获取锁的线程进入休眠或者阻塞,除非当前线程异常,否则其他线程尝试获取锁必须一直等待

JDK1.5之后发布,加入了concurrent包。包内提供了Lock类,用来扩展的加锁功能。Lock弥补了synchronized的局限,提供了更加细粒度的加锁功能。

二.ReentrantLock介绍

Lock lock = new ReentrantLock();

Lock是一个接口,ReentrantLock锁是lock的一个实现

Lock接口的几个方法的总体描述

/**
 * 尝试锁
 */
package concurrent.t03;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test_02 {
	Lock lock = new ReentrantLock();
	
	void m1(){
		try{
			lock.lock();
			for(int i = 0; i < 10; i++){
				TimeUnit.SECONDS.sleep(1);
				System.out.println("m1() method " + i);
			}
            //在lock和unlock之间可以调用m1()方法(递归调用),俗称可重入。
            // m1();
		}catch(InterruptedException e){
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	void m2(){
		boolean isLocked = false;
		try{
			// 尝试锁, 如果有锁,无法获取锁标记,返回false。
			// 如果获取锁标记,返回true
			// isLocked = lock.tryLock();
			
			// 阻塞尝试锁,阻塞参数代表的时长,尝试获取锁标记。
			// 如果超时,不等待。直接返回。
			isLocked = lock.tryLock(5, TimeUnit.SECONDS); 
			
			if(isLocked){
				System.out.println("m2() method synchronized");
			}else{
				System.out.println("m2() method unsynchronized");
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(isLocked){
				// 尝试锁在解除锁标记的时候,一定要判断是否获取到锁标记。
				// 如果当前线程没有获取到锁标记,会抛出异常。
				lock.unlock();
			}
		}
	}
	
	public static void main(String[] args) {
		final Test_02 t = new Test_02();
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.m1();
			}
		}).start();
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				t.m2();
			}
		}).start();
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值