HTTP去请求就会像上面那种自动加个new String(),就会导致锁的线程不是同一个对象,可以通过获取对应常量达到效果
但还有个问题,字符串常量是存在JVM的常量池中。常量池是全局的。所以在其他地方有引用到相关常量时,就会造成一定的性能问题(如清华入学,锁的字符串常量一致时)
所以希望不同的接口功能使用不同的锁资源。就可以使用ConcurrentHashMap,在接口外设置交卷的ConcurrentHashMap对象,在接口中,看看是否有对应字符串,无
以下是一个利用ConcurrentHashMap
对字符串上锁的示例:
import java.util.concurrent.ConcurrentHashMap; public class ConcurrentHashMapLockExample { private static final ConcurrentHashMap<String, Object> locks = new ConcurrentHashMap<>(); public static void doSomethingUnderLock(String key) { // 获取锁对象 Object lockObject = locks.computeIfAbsent(key, k -> new Object()); synchronized (lockObject) { // 关键代码部分,在锁的保护下执行 System.out.println("Thread " + Thread.currentThread().getName() + " is executing for key: " + key); } } public static void main(String[] args) { String key1 = "data1"; String key2 = "data2"; Thread thread1 = new Thread(() -> doSomethingUnderLock(key1)); Thread thread2 = new Thread(() -> doSomethingUnderLock(key1)); Thread thread3 = new Thread(() -> doSomethingUnderLock(key2)); thread1.start(); thread2.start(); thread3.start(); } }
在这个示例中:
-
首先创建了一个
ConcurrentHashMap
名为locks
,用于存储不同字符串对应的锁对象。 -
在
doSomethingUnderLock
方法中,通过computeIfAbsent
方法,如果ConcurrentHashMap
中不存在给定key
对应的锁对象,就创建一个新的Object
作为锁对象并放入ConcurrentHashMap
中。这样确保了每个不同的字符串都有唯一的锁对象与之对应。 -
然后使用
synchronized
关键字对获取到的锁对象进行同步,这样可以保证对于相同的字符串,在同一时间只有一个线程可以执行关键代码部分。
在这个例子中,新创建的Object
是对应key
(字符串)在ConcurrentHashMap
中的value
。 具体来说,当调用locks.computeIfAbsent(key, k -> new Object());
时,如果ConcurrentHashMap
中不存在给定的key
,那么就会创建一个新的Object
实例并作为这个key
的对应值存储在ConcurrentHashMap
中。这样做的目的是为了每个不同的key
都有一个唯一的对象可以用来作为锁,以确保不同的key
在多线程环境下可以独立地进行同步操作。
这个示例展示了如何利用ConcurrentHashMap
来为不同的字符串创建独立的锁,以实现对不同资源的并发安全访问。例如,在多线程环境下,如果有多个线程需要对不同的数据集进行操作,而每个数据集可以用一个字符串来标识,就可以使用这种方式来确保对每个数据集的操作都是线程安全的。
借鉴:B站-徐庶老师视频