文中的例子从线程调度上讲不够严谨。原因是没输出,并不代表线程无法进入方法,有可能是线程一直没有被调度。
不过拿来讲Synchronized是可以的,因为两个有竞争线程,输出结果必然是先进入的线程输出完并且退出方法后,另一个才能输出
public class SycTest {
private Object ob = new Object();
static synchronized void abc(String x){
print(x);
}
synchronized void cde(String y){
print(y);
}
synchronized void def(String y){
print(y);
}
void fgh(String z){
synchronized (ob){
print(z);
}
}
static void print(String c){
for(int i=0;i<4 ;i++){
System.out.print(c+",");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
SycTest test = new SycTest();
Thread t1 = new Thread(()->{test.cde("t1");});
Thread t2 = new Thread(()->{test.def("t2");});
Thread t3 = new Thread(()->{abc("t3");});
Thread t4 = new Thread(()->{test.cde("t4");});
Thread t5 = new Thread(()->{test.fgh("t5");});
List<Thread> threads = new ArrayList<>(5);
threads.add(t1);
threads.add(t2);
threads.add(t3);
threads.add(t4);
threads.add(t5);
threads.parallelStream().forEach(t->t.start());
}
}
跑几次后,代码输出结果
t3,t2,t5,t3,t2,t5,t3,t2,t5,t3,t5,t2,t1,t1,t1,t1,t4,t4,t4,t4,
t3,t5,t4,t3,t4,t5,t3,t5,t4,t3,t5,t4,t1,t1,t1,t1,t2,t2,t2,t2,
t3,t2,t5,t5,t2,t3,t2,t5,t3,t2,t5,t3,t4,t4,t4,t4,t1,t1,t1,t1,
t3,t1,t5,t3,t1,t5,t3,t1,t5,t3,t1,t5,t4,t4,t4,t4,t2,t2,t2,t2,
我们可以看到
t1的4次输出后t4才有机会输出或者相反。(同一个synchronized方法一次只能由一个线程执行)
t1(4)的4次输出后t2才有机会输出或者相反。(同一个实例的synchronized方法一次只能由一个线程执行)
t3的能够及时输出,没有一定的先后顺序。(synchronized修饰的static方法和实例方法可以同时执行,并不冲突。)
t5的能够及时输出,没有一定的先后顺序。(why)
上面4点的解释,也算是java基础之一
1.synchronized修饰的实例方法是对当前对象实例加锁。
2.基于第1点,同一对象实例的不同synchronized方法不能同时执行,所以现实中应做好考虑。
3.synchronized修饰的static方法其实锁定的当前对象的Class对象,而Class对象只有一个。
4.synchronized块中,明确指定了synchronized的锁定的对象,就可能不会受第1点描述的影响。如果synchronized(this)的话就相当于第1点。
5.基于第3点,一个类中的两个synchronized修饰的static方法不能同时执行。
关于synchronized(this)和第5点自行写例子验证。
想深入synchronized在JVM层面上的实现可以参考"死磕Synchronized底层实现" 概论链接https://juejin.im/post/5bfe6ddee51d45491b0163eb
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。