java中synchronized的轻量级锁和重量级锁是什么
时间: 2023-05-26 15:01:44 浏览: 130
A:在Java中,synchronized关键字是用于实现并发安全的机制之一。在具体实现上,synchronized关键字会根据竞争情况,使用不同的锁来保证线程安全。其中,轻量级锁和重量级锁是两种不同的锁机制,具体如下:
1. 轻量级锁(Lightweight lock):在没有线程竞争的情况下,使用轻量级锁来提高并发性能。轻量级锁的实现机制是,在对象的头部存储一个指针,指向持有该对象锁的线程的栈帧,同时利用CAS(Compare-And-Swap)指令来实现锁的获取和释放,从而避免了操作系统级别的线程切换,提高并发性能。
2. 重量级锁(Heavyweight lock):在发生线程竞争的情况下,会升级为重量级锁来保证线程安全。重量级锁的实现机制是,当多个线程竞争同一个对象的锁时,会将其中一个线程阻塞,直到有其他线程释放锁,从而实现同步效果。重量级锁的缺点是会引起线程的频繁阻塞和唤醒,降低了并发性能,因此在实际应用中尽可能使用轻量级锁来提高程序的并发性能。
相关问题
java中synchronized的轻量级锁和重量级锁的用法
在 Java 中,synchronized 是用来实现线程同步的关键字,它包含了两种锁的实现方式:轻量级锁和重量级锁。
轻量级锁:轻量级锁是指在没有竞争的情况下,使用 CAS 操作来进行加锁和解锁操作。当线程占有锁时,使用 CAS 将锁对象的对象头的 Mark Word 修改为指向锁拥有的线程的栈帧的锁记录。轻量级锁的优点在于,在竞争不激烈的情况下,加锁和解锁的开销较小,性能较高。
重量级锁:重量级锁是指在竞争激烈的情况下,使用操作系统的互斥量来进行加锁和解锁操作。当锁对象被多个线程争抢时,轻量级锁会逐渐升级为重量级锁,这时需要通过操作系统的互斥量来进行加锁和解锁操作,开销较大。
在 Java 中,synchronized 默认使用的是重量级锁,但是当 synchronized 应用在方法上时,JVM 会自动地选择合适的锁类型,包括轻量级锁和偏向锁等。因此,在使用 synchronized 关键字时,需要根据实际情况进行权衡和选择,以达到更好的性能和效果。
解释一下 Synchronized 中 偏向锁 轻量级锁 重量级锁的 含义,并且用例子解释一下
Synchronized 是 Java 中用于实现线程同步的关键字,它可以保证在同一时刻只有一个线程可以访问被 Synchronized 修饰的代码块或方法。在实现线程同步时,Synchronized 使用了不同的锁,包括偏向锁、轻量级锁和重量级锁。
偏向锁是一种针对单线程场景的优化锁,它会在第一次获取锁时,将当前线程 ID 记录在锁的对象头中,之后该线程再次获取锁时,无需竞争锁资源,直接获取锁即可。举个例子:
```java
public class BiasLockExample {
private static Object lock = new Object();
public static void main(String[] args) {
long start = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
synchronized (lock) {
// do something
}
}
System.out.println("Time cost: " + (System.currentTimeMillis() - start) + "ms");
}
}
```
在以上代码中,由于所有的锁都是在同一个线程中获取的,因此会使用偏向锁进行优化,从而提高了程序的执行效率。
轻量级锁是一种适用于竞争不激烈的场景的锁,它会在第一次获取锁时,将对象头中的信息复制到线程栈中,然后通过 CAS 操作来更新对象头中的信息,如果更新成功,则表示该线程获取了锁,如果失败,则需要升级为重量级锁。举个例子:
```java
public class LightweightLockExample {
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " got the lock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " got the lock");
}
}).start();
}
}
```
在以上代码中,由于第一个线程获取锁后会休眠 5 秒钟,因此第二个线程需要等待第一个线程释放锁之后才能获取锁,而这时就会使用轻量级锁进行优化。
重量级锁是一种适用于竞争激烈的场景的锁,它会导致线程阻塞,从而消耗大量的系统资源。举个例子:
```java
public class HeavyweightLockExample {
private static Object lock = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " got the lock");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(() -> {
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " got the lock");
}
}).start();
}
}
```
在以上代码中,由于两个线程同时竞争同一个锁,因此会使用重量级锁进行优化,从而导致第二个线程需要等待第一个线程释放锁之后才能获取锁,这样会导致线程阻塞,从而影响程序的执行效率。
阅读全文