reentrantlock 必须要必须要必须要手动释放锁
使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放
使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待,例如代码
1 /** 2 * 使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行 3 * 可以根据tryLock的返回值来判定是否锁定 4 * 也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以要注意unclock的处理,必须放到finally中 5 */ 6 void m2() { 7 /* 8 boolean locked = lock.tryLock(); 9 System.out.println("m2 ..." + locked); 10 if(locked) lock.unlock(); 11 */ 12 13 boolean locked = false; 14 15 try { 16 locked = lock.tryLock(5, TimeUnit.SECONDS); 17 System.out.println("m2 ..." + locked); 18 } catch (InterruptedException e) { 19 e.printStackTrace(); 20 } finally { 21 if(locked) lock.unlock(); 22 } 23 24 }
使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应,在一个线程等待锁的过程中,可以被打断
1 /** 2 * reentrantlock用于替代synchronized 3 * 由于m1锁定this,只有m1执行完毕的时候,m2才能执行 4 * 这里是复习synchronized最原始的语义 5 * 6 * 使用reentrantlock可以完成同样的功能 7 * 需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍) 8 * 使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放 9 * 10 * 使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待 11 * 12 * 使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应, 13 * 在一个线程等待锁的过程中,可以被打断 14 * 15 * @author mashibing 16 */ 17 package com.hamster.concurrent.c020; 18 19 import java.util.concurrent.TimeUnit; 20 import java.util.concurrent.locks.Lock; 21 import java.util.concurrent.locks.ReentrantLock; 22 23 public class ReentrantLock4 { 24 25 public static void main(String[] args) { 26 Lock lock = new ReentrantLock(); 27 28 29 Thread t1 = new Thread(()->{ 30 try { 31 lock.lock(); 32 System.out.println("t1 start"); 33 TimeUnit.SECONDS.sleep(Integer.MAX_VALUE); 34 System.out.println("t1 end"); 35 } catch (InterruptedException e) { 36 System.out.println("interrupted!"); 37 } finally { 38 lock.unlock(); 39 } 40 }); 41 t1.start(); 42 43 Thread t2 = new Thread(()->{ 44 try { 45 //lock.lock(); 46 lock.lockInterruptibly(); //可以对interrupt()方法做出响应 47 System.out.println("t2 start"); 48 TimeUnit.SECONDS.sleep(5); 49 System.out.println("t2 end"); 50 } catch (InterruptedException e) { 51 System.out.println("interrupted!"); 52 } finally { 53 lock.unlock(); 54 } 55 }); 56 t2.start(); 57 58 try { 59 TimeUnit.SECONDS.sleep(1); 60 } catch (InterruptedException e) { 61 e.printStackTrace(); 62 } 63 t2.interrupt(); //打断线程2的等待 64 //ReentrantLock.lockInterruptibly允许在等待时由其它线程调用等待线程的Thread.interrupt方法来中断等待线程的等待而直接返回,这时不用获取锁,而会抛出一个InterruptedException 65 } 66 }