最近在学习研究synchronized关键字,发现有个疑问:
在同一个类中,有多个sync方法,当线程调用其中的一个方法的时候,其他的线程能调用其他的sync方法么?
为此做了简单的测试(详细的测试过程略过,读者可使用测试代码自行操作),得出结论如下:
- 类中存在一个或者多个static sync方法,同一个时间只能有一个线程运行该类的sync方法,sync锁住的是该类的这个方法
- 类中存在一个或者多个sync的非静态方法,实例化该类的对象,同一个时间只能有一个线程运行该对象的sync方法,sync锁住的是当前实例化的这个对象
- 类中既存在一个或者多个static sync方法和一个或者多个sync的非静态方法,规则不受影响,即static sync只和static sync方法存在锁的竞争,sync的非静态方法只和sync的非静态方法存在锁的竞争。
测试代码如下,读者可自行测试:
public class TestPojo {
private String filed;
public synchronized String getFiled() {
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "filed";
}
public void setFiled(String filed) {
this.filed = filed;
}
public String getFiledNoSync() {
return "test";
}
public static String getFiled2() {
synchronized (TestPojo.class){
return "staticSynchronized 2";
}
}
public static String getFiled3() {
synchronized (TestPojo.class){
return "staticSynchronized 3";
}
}
}
public static void main(String[] args) {
//测试的时候根据需要调整TestPojo类中的synchronized关键字所修饰的内容
TestPojo ts = new TestPojo();
new Thread(() ->{
String filed = ts.getFiled();
System.out.println(filed);
}).start();
System.out.println("1 运行完了");
new Thread(() ->{
String filed = ts.getFiled2();
System.out.println(filed);
}).start();
}
PS:学习笔记整理,有问题欢迎评论指正