我们可以利用池里String的对象来做锁,实现对资源的控制。比如一个城市的某种资源同一时间只能一个线程访问,那就可以把城市名的String对象作为锁,放到常量池中去,同一时间只能一个线程获得。 具体代码如下: importjava.util.concurrent.ExecutorService;importjava.util.concurrent.Executors;publicclassStringInternMultiThread{...
Stringaaa="fff";Stringbbb=newString("fff");// 此时aaa和bbb的引用不同,但是值相同//而synchronized(aaa)和synchronized(bbb)是不会产生互斥锁的,因为aaa和bbb此时不是同一个对象;//如果此时执行:aaa.intern();// 那么aaa和bbb就是一个对象了(注意只是执行了aaa.intern()没有执行bbb.intern())// 所以...
我们用String作为锁,并希望它能像Object一样,不同变量加锁互不影响。然而,有时2个String对象可能指向常量池中同一个字符串,导致其加锁互相影响。一个例子如下,若在2个类中,使用了字符串字面量赋值的方式声明2个String对象,并用synchronized关键字对两个String对象分别加锁,由于字符串常量池,2个String对象中的字符...
从结果可以看出,每个线程创建前使用new String(lock)会产生不同的锁,造成线程同步失败。所以在使用的时候要特别注意这点,new String(lock)是会产生不同的对象,他们所指向的对象锁是不同的。 StringBulider和StringBuffer的问题 由上引申到StringBuilder和StringBuffer,这也是使用字符串作为同步锁需要注意的问题。比如某些...
2.当执行s1.intern();时,发现常量池中不存在“1a”,故在常量池中复制一份与s1相同的引用,即直接将s1锁指向的字符串“1a”的地址复制一份到常量池中。 3.此时再执行String s2 = "1a";,拿到的就和s1相同了,从而有了语句3和4的true。 如果将语句1和2对调,则会出现结果: 代码语言:javascript 代码运行次数...
在Java中,String#intern()方法是一个本地方法,它的实现与具体的Java虚拟机(JVM)实现有关。String#intern()方法的主要作用是将字符串添加到字符串常量池或从字符串常量池中获取该字符串的引用。 以下是String#intern()方法的实现概述: 如果字符串常量池中已经存在该字符串,则返回该字符串的引用。 如果字符串...
// 当map取值为null时再加锁判断 synchronized(map) { if(val = map.get(key) == null) { // set some value to map... } } } return map.get(key); } 中级技巧 - String.intern() 乐观锁不能很好解决大量写冲突问题,但是如果很多场景下,锁实际上只是针对某个用户或者某个订单。比...
初级技巧 - 乐观锁乐观锁适合这样的场景:读不会冲突,写会冲突。同时读的频率远大于写。以下面的代码为例,悲观锁的实现:乐观锁的实现:中级技巧 - String.intern()乐观锁不能很好解决大量写冲突问题,但是如果很多 java 余额 加锁 字符串 乐观锁 加锁
String syncKey = key + x; synchronized (syncKey) {} 只有保证两个字符串变量最终结果是同一个对象时锁才能生效 最方便的解决办法是使用字符串的intern()方法。 intern() 返回常量池中的字符串对象,相同两个字符串的值相同,则返回的是同一个对象 ...