当前位置: 代码迷 >> 综合 >> java的两种可重入锁
  详细解决方案

java的两种可重入锁

热度:12   发布时间:2024-01-26 19:48:52.0

可重入锁
可重入锁也叫递归锁,它俩等同于一回事,指的是同一线程外层函数获得锁之后,内层递归函数仍然能获得该锁的代码,同一线程在外层方法获取锁的时候,再进入内层方法会自动获取锁。也就是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块。ReentrantLock 和 synchronized 就是典型的可重入锁!
看了上面的解释是不是一脸懵逼,举个通俗易懂的例子来看一下,上代码!
(1). 基于 synchronized

 

public class ReentrantLockTest {public static void main(String[] args) {Phone phone = new Phone();// 第一个线程new Thread(() -> {phone.sendMsg();}, "t1").start();// 第二个线程new Thread(() -> {phone.sendMsg();}, "t2").start();}
}class Phone {// 发送短信同步方法public synchronized void sendMsg() {System.out.println(Thread.currentThread().getName() + " called sendMsg()");// 进入另外一个同步着的方法sendEmail();}// 发送邮件同步方法public synchronized void sendEmail() {System.out.println(Thread.currentThread().getName() + " ******called sendEmail()");}
}

运行结果:

 

t1 called sendMsg()             // t1线程在外层方法获取锁的时候
t1 ******called sendEmail()     // t1再进入内层方法会自动获取锁
t2 called sendMsg()
t2 ******called sendEmail()

(2). 基于 ReentrantLock

 

public class ReentrantLockTest {public static void main(String[] args) {Phone phone = new Phone();// 第一个线程Thread t1 = new Thread(phone, "t1");// 第二个线程Thread t2 = new Thread(phone, "t2");t1.start();t2.start();}
}class Phone implements Runnable {ReentrantLock lock = new ReentrantLock();// 发送短信方法public void sendMsg() {lock.lock();try {System.out.println(Thread.currentThread().getName() + " called sendMsg()");// 进入另一个方法sendEmail();} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}// 发送邮件方法public void sendEmail() {lock.lock();try {System.out.println(Thread.currentThread().getName() + " ******called sendEmail()");} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}}@Overridepublic void run() {sendMsg();}
}

运行结果:

 

t1 called sendMsg()             // t1线程在外层方法获取锁的时候
t1 ******called sendEmail()     // t1再进入内层方法会自动获取锁
t2 called sendMsg()
t2 ******called sendEmail()

通过上述代码演示,相对而言会比之前稍微清晰那么一点了吧!