1、synchronized 关键字的锁对象是谁?
①当synchronized 关键字加在实例方法上,那么锁对象是当前类实例
示例代码
synchronized void a() {
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a");
}
synchronized void b() {
System.out.println("b");
}
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
new Thread(() -> {
test.b();
}).start();
new Thread(() -> {
test.a();
}).start();
}
②、当synchronized 关键字加在静态方法上,那么锁对象是当前类
示例代码
static synchronized void a() {
System.out.println("aaaa");
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a");
}
static synchronized void b() {
System.out.println("b");
}
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
ThreadTest test1 = new ThreadTest();
new Thread(() -> {
ThreadTest.a();
}).start();
new Thread(() -> {
ThreadTest.b();
}).start();
}
2、synchronized 关键字可重入吗?
synchronized 是可重入的!
示例代码
synchronized void a() {
System.out.println("aaaa");
b();
try {
Thread.sleep(3000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("a");
}
synchronized void b() {
System.out.println("b");
}
public static void main(String[] args) {
ThreadTest test = new ThreadTest();
test.a();
}
a方法中调用b方法。因为当前的锁对象是类的实例,调用a方法时,可以立马调用b方法,说明sychronized是可重入的。
3、synchronized是如何加锁的?
①从字节码层面看
Jvm 生了2个字节码命令
monitorenter代表进入
monitorexit代表退出
②从jvm层面看
问题一:synchronized的锁信息存放在哪里?
synchronized 的锁信息存放在对象头中。
对象头中包含2个部分
1、MarkDown
2、示例数据(存放对象的字段内容)
MarkDown 中包含了锁的标记位。
其中锁有偏向锁,轻量级锁,重量级锁。
3者的使用场景如下:1个线程进入临界区,多个线程交替进入临界区,多个线程同时进入临界区
偏向锁
只有1个线程进入临界区,线程获取锁之后,不会释放锁,再次进入的时候无需再次加锁
轻量级锁
多个线程交替进入临界区,以自旋的方式进行忙循环。线程不会被挂起。也就是线程不会被切换出去。
重量级锁
线程会被挂起,会被切换出去。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。