1700451289
1700451290
*1
1700451291
1700451292
一个倒三角形,没有产生死锁,正常执行,这是为何呢?很奇怪,是吗?那是因为在运行时当前线程(Thread-0)获得了foo对象的锁(synchronized虽然是标注在方法上的,但实际作用的是整个对象),也就是该线程持有了foo对象的锁,所以它可以多次重入fun方法,也就是递归了。可以这样来思考该问题,一个宝箱有N把钥匙,分别由N个海盗持有(也就是我们Java中的线程了),但是同一时间只能由一把钥匙打开宝箱,获取宝物,只有在上一个海盗关闭了宝箱(释放锁)后,其他海盗才能继续打开锁获取宝物,这里还有一个规则:一旦一个海盗打开了宝箱,则该宝箱内的所有宝物对他来说都是开放的,即使是“宝箱中的宝箱”(即内箱)对他也是开放的。可以用以下代码来表述。
1700451293
1700451294
class Foo implements Runnable{
1700451295
1700451296
public void run(){
1700451297
1700451298
method1();
1700451299
1700451300
}
1700451301
1700451302
public synchronized void method1(){
1700451303
1700451304
method2();
1700451305
1700451306
}
1700451307
1700451308
public synchronized void method2(){
1700451309
1700451310
//Do Something
1700451311
1700451312
}
1700451313
1700451314
}
1700451315
1700451316
方法method1是synchronized修饰的,方法method2也是synchronized修饰的,method1调用method2是没有任何问题的,因为是同一个线程持有对象锁,在一个线程内多个synchronized方法重入完全是可行的,此种情况下不会产生死锁。
1700451317
1700451318
那什么情况下会产生死锁呢?看如下代码:
1700451319
1700451320
//资源A
1700451321
1700451322
static class A{
1700451323
1700451324
public synchronized void a1(B b){
1700451325
1700451326
String name=Thread.currentThread().getName();
1700451327
1700451328
System.out.println(name+“进入A.a1()”);
1700451329
1700451330
try{
1700451331
1700451332
//休眠1秒,仍然持有锁
1700451333
1700451334
Thread.sleep(1000);
1700451335
1700451336
}catch(Exception e){
1700451337
1700451338
//异常处理
[
上一页 ]
[ :1.700451289e+09 ]
[
下一页 ]