-
synchronized的方法连续调用也是线程安全的
synchronized修饰的方法继续调用synchronized修饰的方法,线程也是安全的
public synchronized void methodA(int a, int b) {
};
public synchronized void methodB(int a){
methodA(a, 0);
}
同一个类中synchronized调用另一个synchronized方法(锁重入)可分三种情况
- 都是某个类中的两个方法
Test t = new Test(); t.methodB();
methodB获得的锁对象应该是t,而methodA也需要这把锁,所以不受影响。实际上是JVM跟踪对象被加锁的次数和被释放的次数。次类情况t被加锁两次然后先后再释放两次锁。
-
两个Test类的实例对象
Test t1 = new Test(); Test t2 = new Test(); t1.methodB(); //此时当前线程持有了t1对象的锁 t2.methodB(); //此时当前线程也持有了t2对象的锁
因为当前线程分别持有t1和t2的锁,所以没有任何影响
-
多线程环境下两个线程分别访问 Test t=new Test()中的t,并且调用t.methodB方法,则按线程访问次序执行
thread1获得t的锁->thread1执行methodB->thread1执行methodA->释放t的锁;
thread2获得t的锁->thread2执行methodB->thread2执行methodA->释放t的锁。
可重入锁也支持父子继承的环境中,具体代码演示如下。
// class Sup
public class Sup {
public int i = 10;
synchronized public void operateSupMethod() {
try{
i --;
System.out.println("sup print i=" + i);
Thread.sleep(100);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
// class Sub
public class Sub extends Sup{
synchronized public void operateSubMethod() {
try{
while(i > 0) {
i --;
System.out.println("sub print i=" + i);
Thread.sleep(100);
this.operateSupMethod();
}
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
// class Thread07
public class Thread07 extends Thread{
@Override
public void run() {
super.run();
Sub sub = new Sub();
sub.operateSubMethod();
}
}
// main class
public static void main(String[] args) {
sub();
}
private static void sub() {
Thread07 thread = new Thread07();
thread.start();
}
输出结果
sub print i=9
sup print i=8
sub print i=7
sup print i=6
sub print i=5
sup print i=4
sub print i=3
sup print i=2
sub print i=1
sup print i=0
可见,继承关系中,子类可以通过“可重入锁”调用父类的同步方法的