当一个线程进入一个对象的synchronized方法之后,其它线程能否进入该对象的其他方法?
答:很明显当其它方法是非synchronized方法时,调用是不受影响的,但当其它方法也是synchronized方法时呢?接下来我们进行实验验证:
class Test{
public synchronized void synchronizedMethod(){
System.out.println("begin calling synchronizedMethod");
try {
Thread.sleep(5000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
}
System.out.println("finsh calling synchronizedMethod");
}
public synchronized void generalMethod(){
System.out.println("call generalMethod");
}
}
Test类中有2个方法,都是synchronized方法,接下来创建两个线程调用:
public class SynchronizedTest {//当两种方法同为普通方法或者静态方法时不能同时进入
static final Test test = new Test();
public static void main(String[] args) {
Thread t1= new Thread(){
@Override
public void run() {
test.synchronizedMethod();
}
};
Thread t2= new Thread(){
@Override
public void run() {
test.generalMethod();
}
};
t1.start();
t2.start();
}
}
结果:
begin calling synchronizedMethod
finsh calling synchronizedMethod
call generalMethod
结果表明当两个方法同为普通的synchronized方法时,线程不能同时调用。当两个方法一个是静态一个是普通方法呢?
class Test{
public synchronized static void synchronizedMethod(){//静态
System.out.println("begin calling synchronizedMethod");
try {
Thread.sleep(5000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
}
System.out.println("finsh calling synchronizedMethod");
}
public synchronized void generalMethod(){//非静态
System.out.println("call generalMethod");
}
}
结果:
begin calling synchronizedMethod
call generalMethod
finsh calling synchronizedMethod
结果表明两个方法可以同时调用。那么当两个方法同时为静态方法呢?
class Test{
public synchronized static void synchronizedMethod(){//静态
System.out.println("begin calling synchronizedMethod");
try {
Thread.sleep(5000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
}
System.out.println("finsh calling synchronizedMethod");
}
public synchronized static void generalMethod(){//静态
System.out.println("call generalMethod");
}
}
结果:
begin calling synchronizedMethod
finsh calling synchronizedMethod
call generalMethod
两个方法不能同时调用。
我们就上面的结果进行总结:
当两个synchronized方法同为普通方法或者静态方法时,不能同时调用;否则可以调用。这是因为,当调用synchronized普通方法时,锁住的是当前的this,而调用synchronized锁住的是当前类的字节码;两个方法锁住对象不同,所以可以同时调用。