关于 Synchronized 关键字,这篇文章写的是非常清楚了: [Java 并发]深入浅出 synchronized 与锁 Synchronized 是可重入锁,今天这篇文章就通过代码直观展示下它的可重入特性
在展示之前,我们再来强调一下,什么是可重入: 可重入就是在使用 Synchronized 时,当一个线程得到一个对象锁之后,再次请求这个对象锁时是可以再次得到该对象的锁的 那么在一个 Synchronized 方法/块 的内部调用这个类的其他 Synchronized 方法/块 时,是可以得到锁的
用代码直观展示一下:
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");
}
}
public class ThreadRun extends Thread {
@Override
public void run(){
SynchronizedService synchronizedService = new SynchronizedService();
synchronizedService.serviceOne();
}
}
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 修饰的,那么它也是支持父子类继承的 来看个具体的例子:
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();
}
}
}
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();
}
}
}
public class ThreadService extends Thread {
@Override
public void run(){
SubService subService = new SubService();
subService.operateSubMethod();
}
}
public class TestInherit {
public static void main(String[] args) {
ThreadService threadService = new ThreadService();
threadService.run();
}
}
同样的道理我在这里就不重复说了,直接看程序运行结果: 可以很清楚的看到, synchronized 是支持父子类继承的~
参考:
以上, 感谢您的阅读~
|