Lock锁

作者: gczxbb | 来源:发表于2019-08-03 22:57 被阅读0次

    synchronized 锁和 Lock 锁的区别

    Lock 锁,Java类,synchronized,关键字。
    synchronized 无法判断是否获得锁,获得失败进入阻塞,Lock 类通过 tryLock()方法,尝试获取,失败不会阻塞。
    synchronized 同步完成自动释放锁,Lock 类在 finally {} 代码块手动释放。

    一、Lock锁

    创建一个Runnable,实现run方法。

    public void run() {
        String threadName = Thread.currentThread().getName();
        lock.lock();
        try {
            Log.d(TAG, "线程:" + threadName + " 获得锁。");
            Thread.sleep(5000);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            Log.d(TAG, "线程:" + threadName + " 获得锁。");
        }
    }
    

    开启两个线程,运行LockRunnable任务。

    LockRunnable lockRunnable = new LockRunnable();
    Thread one = new Thread(lockRunnable);
    one.start();
    Thread two = new Thread(lockRunnable);
    two.start();
    

    第一个线程先获得锁,另一个线程等待,直到unlock()方法释放锁,第二个线程才会获得锁,synchronized 无法判断线程是否获得锁,Lock类有一个tryLock()方法,改变代码。

    public void run() {
        String threadName = Thread.currentThread().getName();
        if (lock.tryLock()) {
            try {
                Log.d(TAG, "线程:" + threadName + " 获得锁。");
                Thread.sleep(5000);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        } else {
            Log.d(TAG, "线程:" + threadName + " 获取锁失败。");
        }
    }
    

    修改run方法,一个线程在Lock的tryLock方法,尝试获取锁,判断该线程是否获得锁,成功获取,返回标志继续执行,未成功获取锁也不会等待,返回false,继续走else方法,synchronized关键字当线程竞争失败时会阻塞等待。
    synchronized同步代码执行完毕,自动释放锁,Lock类需要在finally代码块手动释放,Lock.unlock()方法。

    二、lockInterruptibly方法

    Lock的lock方法,第一个线程获得锁,第二个线程休眠。在当前条件下,执行休眠线程2的中断方法。

    //线程1
    LockRunnable lockRunnable = new LockRunnable();
    Thread one = new Thread(lockRunnable);
    one.start();
    try {
        //确保one先竞争到锁
        Thread.sleep(500);
    }catch (Exception e){
    }
    //线程2
    Thread two = new Thread(lockRunnable);
    two.start();
    
    try {
        //让竞争锁失败而休眠的2线程中断。线程2仍会休眠,
        //线程1释放锁后,线程2竞争到锁,执行时sleep会检查到中断状态,异常
        Thread.sleep(1000);
        two.interrupt();
    }catch (Exception e){
    }
    

    线程2处于竞争锁失败的休眠中,lock方法上锁,线程2对中断方法不感冒,一旦获取到锁,在sleep方法时,会根据中断标志抛出异常。
    Lock的lockInterruptibly方法,在线程2休眠时,中断方法,会导致线程2在等待锁的lockInterruptibly方法处抛出InterruptedException异常,这时,线程2并未获得锁,finally代码段释放锁将发生IllegalMonitorStateException崩溃。


    任重而道远

    相关文章

      网友评论

          本文标题:Lock锁

          本文链接:https://www.haomeiwen.com/subject/nwkjdctx.html