ReentrantLock使用详解(3)之测试锁与超时

我在上面的这篇博客中,曾经写到过线程在获取锁的过程中是无法中断的。

但是ReentrantLock提供了tryLock()、tryLock(long timeout, TimeUnit unit)、lock.lockInterruptibly()


tryLock() 方法试图申请一个锁,在成功获得锁后返回true,否则,立即返回false,而且线程可以立即离开去做其他的事情。

tryLock(long timeout, TimeUnit unit) 是一个具有超时参数的尝试申请锁的方法,阻塞时间不会超过给定的值;如果成功则返回true

lockInterruptibly() 获得锁,但是会不确定地发生阻塞。如果线程被中断,抛出一个InterruptedException异常。


如果当前获得锁的线程在做大量耗时的工作,使用lock.lock()方法申请锁的线程会一直阻塞,这样就降低了多线程的效率。而使用tryLock()方法申请锁,如果锁不可用则线程不会阻塞,转而可以去做其他工作。代码实例如下:

  1. public class ReentrantLockTest4 {  
  2.   
  3.     private ReentrantLock lock = new ReentrantLock();  
  4.       
  5.     public void tryLockTest() throws InterruptedException {  
  6.           
  7.         long beginTime = System.currentTimeMillis();  
  8.         while(System.currentTimeMillis() - beginTime <100) {}  
  9.         // 当前线程尝试获得锁,如果获得锁返回true,否则返回false  
  10.         if(lock.tryLock()) {  
  11.             try{  
  12.                 System.out.println(Thread.currentThread().getName() + " tryLock get lock");  
  13.             } finally {  
  14.                 lock.unlock();  
  15.                 System.out.println(Thread.currentThread().getName() + " tryLock release lock");  
  16.             }  
  17.         } else {  
  18.             System.out.println(Thread.currentThread().getName() + " tryLock can not get lock");  
  19.         }  
  20.           
  21.     }  
  22.       
  23.       
  24.     public void lockTest() {  
  25.         try{  
  26.             // 当前线程在锁可用时直接获得锁,锁不可用时阻塞当前线程  
  27.             lock.lock();  
  28.             System.out.println(Thread.currentThread().getName() + " lock get lock");  
  29.             long beginTime = System.currentTimeMillis();  
  30.             while(System.currentTimeMillis() - beginTime <1000) {}  
  31.         } finally {  
  32.             lock.unlock();  
  33.             System.out.println(Thread.currentThread().getName() + " lock release lock");  
  34.         }  
  35.   
  36.     }  
  37.       
  38.     public static void main(String[] args) {  
  39.         // TODO Auto-generated method stub  
  40.         final ReentrantLockTest4 test = new ReentrantLockTest4();  
  41.         Thread tryLock = new Thread(new Runnable() {  
  42.             public void run() {  
  43.                 try {  
  44.                     test.tryLockTest();  
  45.                 } catch (InterruptedException e) {  
  46.                     // TODO Auto-generated catch block  
  47.                     e.printStackTrace();  
  48.                 }  
  49.             }  
  50.         },"tryLock_thread");  
  51.           
  52.         Thread lock = new Thread(new Runnable() {  
  53.             public void run() {  
  54.                 test.lockTest();  
  55.             }  
  56.         },"lock_thread");  
  57.           
  58.         tryLock.start();  
  59.         lock.start();  
  60.     }  
  61.   
  62. }  
  63.   
  64. 输出结果:  
  65. lock_thread lock get lock  
  66. tryLock_thread tryLock can not get lock  
  67. lock_thread lock release lock  
public class ReentrantLockTest4 {

	private ReentrantLock lock = new ReentrantLock();
	
	public void tryLockTest() throws InterruptedException {
		
		long beginTime = System.currentTimeMillis();
		while(System.currentTimeMillis() - beginTime <100) {}
		// 当前线程尝试获得锁,如果获得锁返回true,否则返回false
		if(lock.tryLock()) {
			try{
				System.out.println(Thread.currentThread().getName() + " tryLock get lock");
			} finally {
				lock.unlock();
				System.out.println(Thread.currentThread().getName() + " tryLock release lock");
			}
		} else {
			System.out.println(Thread.currentThread().getName() + " tryLock can not get lock");
		}
		
	}
	
	
	public void lockTest() {
		try{
			// 当前线程在锁可用时直接获得锁,锁不可用时阻塞当前线程
			lock.lock();
			System.out.println(Thread.currentThread().getName() + " lock get lock");
			long beginTime = System.currentTimeMillis();
			while(System.currentTimeMillis() - beginTime <1000) {}
		} finally {
			lock.unlock();
			System.out.println(Thread.currentThread().getName() + " lock release lock");
		}

	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ReentrantLockTest4 test = new ReentrantLockTest4();
		Thread tryLock = new Thread(new Runnable() {
			public void run() {
				try {
					test.tryLockTest();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		},"tryLock_thread");
		
		Thread lock = new Thread(new Runnable() {
			public void run() {
				test.lockTest();
			}
		},"lock_thread");
		
		tryLock.start();
		lock.start();
	}

}

输出结果:
lock_thread lock get lock
tryLock_thread tryLock can not get lock
lock_thread lock release lock



lock方法不能被中断。如果一个线程在等待获得一个锁时被中断,中断线程在获得锁之前会一直处于 阻塞状态。如果出现死锁,那么lock方法就无法被终止。但是tryLock和lockInterruptibly方法在申请锁的过程中是可以被中断的。代码如下

  1. public class ReentrantLockTest5 {  
  2.       
  3.     private ReentrantLock lock = new ReentrantLock();  
  4.       
  5.     public void tryLockInterruptTest() {  
  6.         long beginTime = System.currentTimeMillis();  
  7.         while(System.currentTimeMillis() - beginTime <100) {}  
  8.         try {  
  9.             if (lock.tryLock(5000, TimeUnit.MILLISECONDS)) {  
  10.                 try{  
  11.                     System.out.println(Thread.currentThread().getName() + " tryLock get lock");  
  12.                 }finally {  
  13.                     lock.unlock();  
  14.                 }  
  15.             }  
  16.         } catch (InterruptedException e) {  
  17.             // TODO Auto-generated catch block  
  18.             System.out.println(Thread.currentThread().getName() + " was interrupted");  
  19.         }  
  20.     }  
  21.       
  22.       
  23.     public void lockTest() {  
  24.         try{  
  25.             // 当前线程在锁可用时直接获得锁,锁不可用时阻塞当前线程  
  26.             lock.lock();  
  27.             System.out.println(Thread.currentThread().getName() + " lock get lock");  
  28.             long beginTime = System.currentTimeMillis();  
  29.             while(System.currentTimeMillis() - beginTime <1000) {}  
  30.         } finally {  
  31.             lock.unlock();  
  32.             System.out.println(Thread.currentThread().getName() + " lock release lock");  
  33.         }  
  34.   
  35.     }  
  36.       
  37.     public static void main(String[] args) {  
  38.         // TODO Auto-generated method stub  
  39.         final ReentrantLockTest5 test =  new ReentrantLockTest5();  
  40.         Thread thread_tryLock = new Thread(new Runnable(){  
  41.             @Override  
  42.             public void run() {  
  43.                 // TODO Auto-generated method stub  
  44.                 test.tryLockInterruptTest();  
  45.             }  
  46.         },"tryLockInterruptTest");  
  47.         Thread thread_lock = new Thread(new Runnable(){  
  48.             @Override  
  49.             public void run() {  
  50.                 // TODO Auto-generated method stub  
  51.                 test.lockTest();  
  52.             }  
  53.         },"lockTest");  
  54.         thread_tryLock.start();  
  55.         thread_lock.start();  
  56.         try {  
  57.             Thread.sleep(200);  
  58.         } catch (InterruptedException e) {  
  59.             // TODO Auto-generated catch block  
  60.             System.out.println("main thread was interrupted");  
  61.         }  
  62.         thread_tryLock.interrupt();  
  63.     }  
  64.   
  65. }  
  66.   
  67.   
  68. 输出结果:  
  69. lockTest lock get lock  
  70. tryLockInterruptTest was interrupted  
  71. lockTest lock release lock  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值