Java的ConcurrentHashMap是使用的分段锁?
轻量级锁
public class LightweightLockExample {
private Object lock = new Object();
private int sharedData;
public void incrementSharedData() {
synchronized (lock) {
sharedData++;
}
}
public int getSharedData() {
synchronized (lock) {
return sharedData;
}
}
public static void main(String[] args) {
LightweightLockExample example = new LightweightLockExample();
// 使用多个线程来访问共享数据
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 1000; j++) {
example.incrementSharedData();
}
}).start();
}
// 等待所有线程执行完毕
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出共享数据的最终值
System.out.println("Final shared data value: " + example.getSharedData());
}
}
重量级锁
public class HeavyweightLockExample {
private final Object lock = new Object();
private int counter;
public void increment() {
synchronized (lock) {
counter++;
}
}
public int getCounter() {
synchronized (lock) {
return counter;
}
}
public static void main(String[] args) {
HeavyweightLockExample example = new HeavyweightLockExample();
// 创建多个线程同时访问共享资源
for (int i = 0; i < 10; i++) {
new Thread(() -> {
for (int j = 0; j < 10000; j++) {
example.increment();
}
}).start();
}
// 等待所有线程完成
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出计数器的值
System.out.println("Final counter value: " + example.getCounter());
}
}
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private final ReentrantLock lock = new ReentrantLock();
private int counter;
public void increment() {
lock.lock(); // 获取锁
try {
counter++;
} finally {
lock.unlock(); // 释放锁
}
}
public int getCounter() {
return counter;
}
public static void main(String[] args) {
// 类似上面的示例,创建线程并访问共享资源
}
}
偏向锁
public class BiasedLockingExample {
// 这个对象用作同步的锁
private final Object lock = new Object();
// 共享资源
private int sharedData;
// 使用synchronized关键字进行同步的方法
public synchronized void synchronizedMethod() {
sharedData++;
}
// 使用对象锁进行同步的方法
public void lockedMethod() {
synchronized (lock) {
sharedData += 2;
}
}
public static void main(String[] args) throws InterruptedException {
// 创建示例对象
BiasedLockingExample example = new BiasedLockingExample();
// 使用
Lambda表达式和Stream API创建并启动多个线程
IntStream.range(0, 10).forEach(i -> {
new Thread(() -> {
// 每个线程多次调用同步方法
for (int j = 0; j < 10000; j++) {
example.synchronizedMethod();
example.lockedMethod();
}
}).start();
});
// 让主线程睡眠一段时间,等待其他线程执行完毕
Thread.sleep(2000);
// 输出共享数据的最终值
System.out.println("Final sharedData value: " + example.sharedData);
}
}
-
偏向锁的使用是由JVM动态决定的,你不能强制JVM使用偏向锁。 -
在高并发环境下,如果锁竞争激烈,偏向锁可能会被撤销并升级到更重的锁状态,如轻量级锁或重量级锁。 -
偏向锁适用于锁被同一个线程多次获取的场景。如果锁被多个线程频繁地争用,偏向锁可能不是最优的选择。
分段锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class SegmentedCounter {
private final int size;
private final Lock[] locks;
private final int[] counters;
public SegmentedCounter(int size) {
this.size = size;
this.locks = new Lock[size];
this.counters = new int[size];
for (int i = 0; i < size; i++) {
locks[i] = new ReentrantLock();
}
}
public void increment(int index) {
locks[index].lock();
try {
counters[index]++;
} finally {
locks[index].unlock();
}
}
public int getValue(int index) {
locks[index].lock();
try {
return counters[index];
} finally {
locks[index].unlock();
}
}
}
微信赞赏
支付宝扫码领红包