2、可重入锁:可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。
可重入锁有
synchronized
ReentrantLock
synchronized的示意图如下:自动获取自动释放
代码如下:
package lock;
public class SynchronizedDemo {
public static void main(String[] args) {
Phone1 phone = new Phone1();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start();
}
}
class Phone1{
public synchronized void sms(){
System.out.println(Thread.currentThread().getName()+"发短信");
call();
}
public synchronized void call(){
System.out.println(Thread.currentThread().getName()+"打电话");
}
}
ReentrantLock的示意图如下:ReentrantLock 和 synchronized 不一样,需要手动释放锁,所以使用 ReentrantLock的时候一定要手动释放锁,并且加锁次数和释放次数要一样。
代码如下:
package lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockDemo {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start();
}
}
class Phone{
private static Lock lock =new ReentrantLock();
public void sms(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"发短信");
call();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void call(){
lock.lock();
try {
System.out.println(Thread.currentThread().getName()+"打电话");
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}