reentrantlock的使用

reentrantlock可以用来代替synchronized

使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放

class ReentrantLockDemo{
    synchronized void m1(){
        for (int i = 0; i < 10; i++) {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(i);
        }
    }

void m2(){
        /**
         * 在 try-finally 外加锁的话,如果因为发生异常导致加锁失败
         * try-finally 块中的代码不会执行
         * 相反,如果在 try{ } 代码块中加锁失败,finally 中的代码无论如何都会执行
         * 但是由于当前线程加锁失败并没有持有 lock 对象锁,程序会抛出异常
         *
         * 详情参考 https://blog.csdn.net/u013568373/article/details/98480603
         */
        lock.lock();    //相当于synchronized(this)
        try {
            for (int i = 0; i < 10; i++) {
                TimeUnit.SECONDS.sleep(1);
                System.out.println(i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

public static void main(String[] args) {
        ReentrantLockDemo r1=new ReentrantLockDemo();
        new Thread(r1::m1).start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(r1::m2).start();
    }

}

reentrantlock可以进行“尝试锁定”trylock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续

void m3(){
       boolean locked=false;
        try {
            locked=lock.tryLock(5,TimeUnit.SECONDS);
            System.out.println("m2...."+locked);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (locked) {
                .....//业务逻辑
                lock.unlock();
            }
        }
    }

指定公平锁,谁等的时间长,线程就得到这把锁

public class ReentrantLock5 extends Thread {
    private static ReentrantLock lock=new ReentrantLock(true);//参数为true表示为公平锁,可以对比输出结果

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            lock.lock();
            try {
                System.out.println(Thread.currentThread().getName()+"获得锁");
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        ReentrantLock5 r1=new ReentrantLock5();
        Thread th1=new Thread(r1);
        Thread th2=new Thread(r1);
        th1.start();
        th2.start();
    }
}

还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应

public class ReentrantLock4 {
    public static void main(String[] args) {
        Lock lock=new ReentrantLock();

        Thread t1=new Thread(()->{
            lock.lock();
            try {
                System.out.println("t1 start");
                TimeUnit.SECONDS.sleep(Integer.MAX_VALUE);
                System.out.println("t1 end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });

        t1.start();

        Thread t2=new Thread(()->{

            try {
                lock.lockInterruptibly(); //可以对interrupt()做出响应
                System.out.println("t2 start");
                TimeUnit.SECONDS.sleep(5);
                System.out.println("t2 end");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }

        });

        t2.start();

        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        t2.interrupt();//打断线程2的等待
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ReentrantLock是Java中的一个可重入锁,它提供了与synchronized关键字类似的功能,但更加灵活和强大。下面是ReentrantLock使用介绍: 1. 创建ReentrantLock对象: ```java ReentrantLock lock = new ReentrantLock(); ``` 2. 获取锁: ```java lock.lock(); // 获取锁,如果锁已被其他线程持有,则当前线程会被阻塞,直到获取到锁为止 ``` 3. 释放锁: ```java lock.unlock(); // 释放锁,如果当前线程持有锁,则释放锁;如果当前线程没有持有锁,则会抛出IllegalMonitorStateException异常 ``` 4. 使用try-finally确保锁的释放: ```java lock.lock(); try { // 执行需要同步的代码块 } finally { lock.unlock(); // 在finally块中释放锁,确保锁的释放 } ``` 5. 使用条件变量: ```java Condition condition = lock.newCondition(); // 创建条件变量 condition.await(); // 当前线程等待,直到其他线程调用signal或signalAll方法唤醒它 condition.signal(); // 唤醒一个等待的线程 condition.signalAll(); // 唤醒所有等待的线程 ``` 6. 公平锁和非公平锁: ReentrantLock可以是公平锁或非公平锁,默认情况下是非公平锁。在构造ReentrantLock对象时,可以传入一个boolean参数来指定是否使用公平锁: ```java ReentrantLock lock = new ReentrantLock(true); // 使用公平锁 ReentrantLock lock = new ReentrantLock(false); // 使用非公平锁 ``` 7. 其他方法: - `isHeldByCurrentThread()`:判断当前线程是否持有锁。 - `getHoldCount()`:获取当前线程持有锁的次数。 - `getQueueLength()`:获取等待获取锁的线程数。 - `hasQueuedThreads()`:判断是否有线程在等待获取锁。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值