//…
}
}
关于同步代码块和同步方法的区别之前写过一个关于这个对比,具体可以看这篇文章。java中的synchronized(同步代码块和同步方法的区别)
深入分析Synchronized关键字
线程堆栈分析
synchronized关键字提供了一种互斥机制,也就是说在同一时刻,只能有一个线程访问同步资源。看下面这段程序:
import java.util.concurrent.TimeUnit;
public class TestSync {
private final static Object lock = new Object();
public void accessResource() {
synchronized(lock) {
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
final TestSync sync = new TestSync();
for(int i &#61;0;i<5;i&#43;&#43;) {
new Thread(){
&#64;Override
public void run() {
sync.accessResource();
}
}.start();
}
}
}
上面的代码定义一个方法accessResource&#xff0c;并且使用synchronized来对代码进行同步&#xff0c;同时定义了5个线程调用accessResource方法&#xff0c;由于synchronized的互斥性&#xff0c;只能有一个线程获得lock的monitor锁&#xff0c;其他线程只能进入阻塞状态&#xff0c;等待获取lock的monitor锁。针对这个monitor锁我们如何从线程堆栈信息来看呢&#xff1f;其实&#xff0c;jstack命令在Java中可以用来打印进程的线程堆栈信息。我们来运行这个Java程序&#xff0c;在终端通过top命令查看运行起来的Java程序的进程id&#xff0c;然后执行jstack ‘pid’。我们来看下打印出来的信息&#xff1a;
29: monitorexit
30: athrow
31: return
Exception table:
from to target type
6 15 18 Class java/lang/InterruptedException
6 25 28 any
28 30 28 any
public static void main(java.lang.String[]);
Code:
0: new #1 // class main/TestSync
3: dup
4: invokespecial #44 // Method “”&#x1f626;)V
7: astore_1
8: iconst_0
9: istore_2
10: goto 27
13: new #45 // class main/TestSync$1
16: dup
17: aload_1
18: invokespecial #47 // Method main/TestSync$1."":(Lmain/TestSync;)V
21: invokevirtual #50 // Method main/TestSync$1.start:()V
24: iinc 2, 1
27: iload_2
28: iconst_5
29: if_icmplt 13
32: return
}
Method main/TestSync$1."":(Lmain/TestSync;)V
21: invokevirtual #50 // Method main/TestSync$1.start:()V
24: iinc 2, 1
27: iload_2
28: iconst_5
29: if_icmplt 13
32: return
}