本文采用两种方式实现并发锁控制,实现线程安全操作并且支持大并发.
package com.cary.test;
import cn.hutool.core.thread.ThreadUtil;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.Striped;
import org.junit.Test;
import java.util.Map;
import java.util.concurrent.locks.Lock;
public class LockTest {
private static final Map<Long, Integer> TRADING_MAP = Maps.newConcurrentMap();
private static final Striped<Lock> STRIPED = Striped.lazyWeakLock(100);
/**
* 采用 Guava Striped 实现细粒度锁
*/
@Test
public void testStriped() {
Long orderId = 100L;
for (int i = 0; i < 1000; i++) {
//并发 +1
ThreadUtil.execute(() -> incrByStriped(orderId));
//并发 -1
ThreadUtil.execute(() -> decrByStriped(orderId));
}
//查看结果
for (int i = 0; i < 1000; i++) {
ThreadUtil.sleep(1000);
System.out.println(TRADING_MAP.get(orderId));
}
}
/**
* 采用 synchronized 实现细粒度锁
*/
@Test
public void testSynchronized() {
Long orderId = 100L;
for (int i = 0; i < 1000; i++) {
//并发 +1
ThreadUtil.execute(() -> incrBySynchronized(orderId));
//并发 -1
ThreadUtil.execute(() -> decrBySynchronized(orderId));
}
//查看结果
for (int i = 0; i < 1000; i++) {
ThreadUtil.sleep(1000);
System.out.println(TRADING_MAP.get(orderId));
}
}
/**
* +1操作
*/
public static void incrByStriped(Long orderId) {
//获取锁
Lock lock = STRIPED.get("OrderId-" + orderId);
lock.lock();
try {
if (TRADING_MAP.containsKey(orderId)) {
TRADING_MAP.put(orderId, TRADING_MAP.get(orderId) + 1);
} else {
TRADING_MAP.put(orderId, 1);
}
} finally {
//释放锁
lock.unlock();
}
}
/**
* -1操作
*/
public static void decrByStriped(Long orderId) {
//获取锁
Lock lock = STRIPED.get("OrderId-" + orderId);
lock.lock();
try {
if (TRADING_MAP.containsKey(orderId)) {
int num = TRADING_MAP.get(orderId);
TRADING_MAP.put(orderId, num - 1);
} else {
TRADING_MAP.put(orderId, -1);
}
} finally {
//释放锁
lock.unlock();
}
}
/**
* +1操作
*/
public static void incrBySynchronized(Long orderId) {
String lock = ("OrderId-" + orderId).intern();
synchronized (lock) {
if (TRADING_MAP.containsKey(orderId)) {
TRADING_MAP.put(orderId, TRADING_MAP.get(orderId) + 1);
} else {
TRADING_MAP.put(orderId, 1);
}
}
}
/**
* -1操作
*/
public static void decrBySynchronized(Long orderId) {
String lock = ("OrderId-" + orderId).intern();
synchronized (lock) {
if (TRADING_MAP.containsKey(orderId)) {
int num = TRADING_MAP.get(orderId);
TRADING_MAP.put(orderId, num - 1);
} else {
TRADING_MAP.put(orderId, -1);
}
}
}
}