Java并发之锁测试与超时理解(lock、lockInterruptibly、trylock)

      为防止代码块受并发访问的干扰,Java语言提供了锁来达到这一目的。假定一个线程调用了方法Fmethod(该方法使用了锁),那么在该线程结束执行方法Fmethod前将具有运行权。假定第二个线程也调用了方法Fmethod,由于第二个线程不能获得锁,将在调用lock方法时被阻塞。它必须等待第一个线程完成Fmethod方法的执行后才能再度被激活。当第一个线程释放锁时,第二个线程才能开始运行:

  • void lock();

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired. 在等待获取锁的过程中休眠并禁止一切线程调度。

      为了保证线程在不能获得锁时可以立即离开去做其他事情,可以使用tryLock方法,该方法试图申请一个锁,在成功获得锁后返回true,否则立即返回false:

if(myLock.tryLock()){
    try{ . . .}    //now the thread owns the lock
    finally{ myLock.unlock();}
}else    //do something else

  • boolean tryLock();

Acquires the lock if it is available and returns immediately with the value true. If the lock is not available then this method will return immediately with the value false. 获取到锁并返回true;获取不到并返回false。

  • boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

If the lock is available this method returns immediately with the value true. If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of three things happens:The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported; or The specified waiting time elapses. 在指定时间内等待获取锁;过程中可被中断。

      此外也可以调用lockInterruptibly方法,当线程在等待期间被中断,将抛出InterruptedException异常,允许程序打破死锁:

  • void lockInterruptibly() throws InterruptedException;

If the lock is not available then the current thread becomes disabled for thread scheduling purposes and lies dormant until one of two things happens:The lock is acquired by the current thread; or Some other thread interrupts the current thread, and interruption of lock acquisition is supported. 在等待获取锁的过程中可被中断。

      下面举例详细说明这四种方法的使用:假如线程A和线程B使用同一个锁LOCK,此时线程A首先获取到锁LOCK.lock(),并且始终持有不释放。如果此时B要去获取锁,有四种方式:

LOCK.lock(): 此方式会始终处于等待中,即使调用B.interrupt()也不能中断,除非线程A调用LOCK.unlock()释放锁。

LOCK.lockInterruptibly(): 此方式会等待,但当调用B.interrupt()会被中断等待,并抛出InterruptedException异常,否则会与lock()一样始终处于等待中,直到线程A释放锁。

LOCK.tryLock(): 该处不会等待,获取不到锁并直接返回false,去执行下面的逻辑。

LOCK.tryLock(10, TimeUnit.SECONDS):该处会在10秒时间内处于等待中,但当调用B.interrupt()会被中断等待,并抛出InterruptedException。10秒时间内如果线程A释放锁,会获取到锁并返回true,否则10秒过后会获取不到锁并返回false,去执行下面的逻辑。

猜你喜欢

转载自blog.csdn.net/jisuanjiguoba/article/details/80095506
今日推荐