JUC之可重入锁(递归锁)
可重入锁(又名递归锁)
理论
指的是同一线程外层函数获得锁之后,内层递归函数仍然能够获得该锁的代码
在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁
也就是说,线程可以进入任何一个它已经拥有的锁所同步着的代码块
ReentrantLock/synchronized就是一个典型的可重入锁
作用:避免死锁
代码
synchronized就是一个典型的可重入锁案例
package Lock;
//1.创建资源类
class Phone{
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName() + "\t invoked sendSMS()");
sendEmail();
}
public synchronized void sendEmail()throws Exception{
System.out.println(Thread.currentThread().getName() + "\t ########invoked sendEmail()");
}
}
public class ReenterLockDemo {
//线程操作资源类
public static void main(String[] args) throws Exception{
Phone phone =new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t1").start();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t2").start();
}
}
t1 invoked sendSMS() //t1线程在外层方法获取锁的时候
t1 ########invoked sendEmail() //t1进入内层方法会自动获取锁
t2 invoked sendSMS()
t2 ########invoked sendEmail()
Process finished with exit code 0
ReentrantLock就是一个典型的可重入锁
package Lock;
//1.创建资源类
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Phone implements Runnable{
public synchronized void sendSMS()throws Exception{
System.out.println(Thread.currentThread().getName() + "\t invoked sendSMS()");
sendEmail();
}
public synchronized void sendEmail()throws Exception{
System.out.println(Thread.currentThread().getName() + "\t ########invoked sendEmail()");
}
Lock lock=new ReentrantLock();
@Override
public void run(){
get();
}
public void get(){
lock.lock();//与下面的unlock对应
lock.lock();
try{
System.out.println(Thread.currentThread().getName() + "\t ########invoked get()");
set();
}finally {
lock.unlock();
lock.unlock();
}
}
public void set(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "\t ########invoked set()");
} finally {
lock.unlock();
}
}
}
public class ReenterLockDemo {
//线程操作资源类
public static void main(String[] args) throws Exception{
Phone phone =new Phone();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t1").start();
new Thread(() -> {
try {
phone.sendSMS();
} catch (Exception e) {
e.printStackTrace();
}
}, "t2").start();
//暂停一会儿线程
try {
TimeUnit.SECONDS.sleep(4); }catch (InterruptedException e){e.printStackTrace();}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
Thread t3 =new Thread(phone,"t3");
Thread t4 =new Thread(phone,"t4");
t3.start();
t4.start();
}
}
t1 invoked sendSMS()
t1 ########invoked sendEmail()
t2 invoked sendSMS()
t2 ########invoked sendEmail()
t3 ########invoked get()
t3 ########invoked set()
t4 ########invoked get()
t4 ########invoked set()
Process finished with exit code 0
还没有评论,来说两句吧...