12 ReentrantLock

  1. ReentrantLock是唯一实现了Lock接口的类,并且提供了更多的方法

  2. 使用这个类的时候,切记手动释放锁

  3. 锁必须声明为一个全局变量,因为每个线程的方法都会把变量保存为一个本地的副本,如果在业务处理中声明了锁的变量,那么不同的线程获取的是不同的锁,是没有办法起到互斥的作用的,所以需要锁对象声明为全局变量,如下图所示:
    public class LockTest{
    public static void main (String[] args){
    private List list = new ArrayList();
    final LockTest lockTest = new LockTest();

     new Thread(){
           public void run(){
           		lockTest.insert(Thread.currentThread());	
           }
     }.start();
     new Thread(){
     	public void run(){
           lockTest.insert(Thread.currentThread());
         }
     }.start();
    

    }
    public void insert(Thread thread){
    Lock lock = new ReentrantLock();//此处线程会拷贝副本
    lock.lock();//加锁
    try{
    System.out.println(thread.getName()+“得到了锁”);
    //业务操作

    }catch(Exception e){
      //
    }finally{
    		System.out.println(thread.getName()+"释放了锁");
    	    lock.unLock();//手动释放锁
    }
    

    }
    }
    注意:这段代码的输出结果可能会让人意向不到,毕竟我们已经在业务操作上进行了加锁。但是现实的输出结果是:
    Thread-0得到了锁
    Thread-1得到了锁
    Thread-1释放了锁
    Thread-0释放了锁

为啥呢?
第二个线程之所以在第一个线程还没有释放锁之前就获得了锁,是因为在这个insert方法中,lock变量是一个局部的变量,每一个线程执行到这个方法的时候,都会将这个变量保存一个副本。
所以我们的加锁的操作获得的是不同的锁,所以线程之间没有进行互斥。
所以,只需要将lock声明为全局变量即可。

2.使用tryLock()获取锁的操作
2.1将lock申明为全局变量
2.2在insert()方法中加入判断:
if(lock.tryLock()){
try{
//上面的代码
}catch(Exception e){
//上面的代码
}finally{
lock.unLock();
}
}
注意这个代码的输出结果为:
Thread-0获得了锁
Thread-1获取锁失败
Thread-0释放了锁。
如此,是正确的输出结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值