synchronized关键字
工具指令介绍:
jps:用户查看当前系统中的 java进程
jstack pid : 用于查看当前进程的堆栈信息
两者结合起来使用:先通过jps找到想要查看的进程的pid,然后再通过 jstack pid来查看该进程的堆栈信息
一、Synchronized锁定范围:
1.synchronized 作用于普通成员方法上时,锁定的是 该方法所属的对象
验证如下:
public class ThisMonitor {
public synchronized void method1(){
System.out.println(Thread.currentThread().getName()+"enter to method1");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void method2(){
System.out.println(Thread.currentThread().getName()+"enter to method2");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ThisMonitor thisMonitor = new ThisMonitor();
new Thread(thisMonitor::method1,"t1").start();
new Thread(thisMonitor::method2,"t2").start();
}
}
如上代码运行后,再通过jps及jstack 查看堆栈信息,如下:
"t2" #13 prio=5 os_prio=0 tid=0x000000001f12d000 nid=0x1b00 waiting for monitor entry [0x000000002068f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThisMonitor.method2(ThisMonitor.java:14)
- waiting to lock <0x000000076b7ac7d0> (a ThisMonitor)
at ThisMonitor$$Lambda$2/1096979270.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
"t1" #12 prio=5 os_prio=0 tid=0x000000001f0fb000 nid=0x49ec waiting on condition [0x000000002058f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at ThisMonitor.method1(ThisMonitor.java:7)
- locked <0x000000076b7ac7d0> (a ThisMonitor)
at ThisMonitor$$Lambda$1/1324119927.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)
如上, - waiting to lock <0x000000076b7ac7d0> (a ThisMonitor) ,说明t2线程在等待 获取ThisMonitor对象的锁。
2.synchronized 作用于静态成员方法上时,锁定的是 Class对象 ,可以简单理解为加载到方法区的类文件
验证如下:
public class ClassMonitor {
public static synchronized void method1(){
System.out.println(Thread.currentThread().getName()+"entor to method1");
try {
TimeUnit.MINUTES.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static synchronized void method2(){
System.out.println(Thread.currentThread().getName()+"entor to method1");
try {