[Java 并发] Synchronized 不是可重入锁吗?能不能直观展示下?
source link: https://www.dynamic-zheng.com/posts/9e1fd16f.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
[Java 并发] Synchronized 不是可重入锁吗?能不能直观展示下?
关于 Synchronized 关键字,这篇文章写的是非常清楚了: [Java 并发]深入浅出 synchronized 与锁
Synchronized 是可重入锁,今天这篇文章就通过代码直观展示下它的可重入特性
在展示之前,我们再来强调一下,什么是可重入: 可重入就是在使用 Synchronized 时,当一个线程得到一个对象锁之后,再次请求这个对象锁时是可以再次得到该对象的锁的
那么在一个 Synchronized 方法/块 的内部调用这个类的其他 Synchronized 方法/块 时,是可以得到锁的
用代码直观展示一下:
/**
* @introduce: 验证 synchronized 是可重入锁
* @author: zll
* @DATE: 2021-3-14 17:28:34
**/
public class SynchronizedService {
synchronized public void serviceOne(){
System.out.println("service one");
serviceTwo();
}
synchronized public void serviceTwo(){
System.out.println("service two");
serviceThree();
}
synchronized public void serviceThree(){
System.out.println("service three");
}
}
/**
* @introduce: 验证 synchronized 是可重入锁
* @author: zll
* @DATE: 2021-3-14 17:28:34
**/
public class ThreadRun extends Thread {
@Override
public void run(){
SynchronizedService synchronizedService = new SynchronizedService();
synchronizedService.serviceOne();
}
}
/**
* @introduce: 验证 synchronized 是可重入锁
* @author: zll
* @DATE: 2021-3-14 17:28:34
**/
public class Run {
public static void main(String[] args) {
ThreadRun thread = new ThreadRun();
thread.start();
}
}
在 SynchronizedService
这个类中, 方法 serviceOne
调用了同样被 synchronized
修饰的 serviceTwo
,方法 serviceTwo
也是调用了同样被 synchronized
修饰的 serviceThree
方法serviceOne
在运行时就获得了 SynchronizedService
对象的锁, 而在 serviceOne
内部,则调用了被 synchronized
修饰 serviceTwo
, 如果 synchronized
不是可重入锁的话,此时方法 serviceTwo
也会去获取 SynchronizedService
对象的锁,但是 SynchronizedService
这个锁在被 serviceOne
占用着,也就是: 如果 synchronized
不是可重入锁的话,就会造成死锁
我们看下程序运行的结果
方法 serviceOne
, serviceTwo
, serviceThree
里的内容都打印了出来,说明没有造成死锁
也就是: synchronized
是可重入锁
扩展: synchronized 也支持父子类继承
如果父子类都是使用 synchronized
修饰的,那么它也是支持父子类继承的
来看个具体的例子:
/**
* @introduce: 验证 synchronized 支持父子类继承
* @author: zll
* @DATE:
**/
public class MainService {
public int i = 10;
synchronized public void operateMainMethod(){
try {
i --;
System.out.println("main service print i = " + i);
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
/**
* @introduce: 验证 synchronized 支持父子类继承
* @author: zll
* @DATE:
**/
public class SubService extends MainService{
synchronized public void operateSubMethod(){
try {
while ( i > 0){
i --;
System.out.println("sub service print i = " + i);
Thread.sleep(100);
this.operateMainMethod();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
/**
* @introduce: 验证 synchronized 支持父子类继承
* @author: zll
* @DATE:
**/
public class ThreadService extends Thread {
@Override
public void run(){
SubService subService = new SubService();
subService.operateSubMethod();
}
}
/**
* @introduce: 验证 synchronized 支持父子类继承
* @author: zll
* @DATE:
**/
public class TestInherit {
public static void main(String[] args) {
ThreadService threadService = new ThreadService();
threadService.run();
}
}
同样的道理我在这里就不重复说了,直接看程序运行结果:
可以很清楚的看到, synchronized
是支持父子类继承的~
- Java 多线程编程核心技术
以上,
感谢您的阅读~
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK