在memcached中我们公司首先根据查询条件获得key,然后查询mem有没有,如果没有将要进行数据库查询,然后add到memecached中,但是如果第一次同一时间大量访问这个key那么同一时间都要访问mysql造成mysql压力巨大,解决方法:
public void method(){
String key = String.valueOf(cityId);
。。。。
synchronized (key) {
。。。
}
}
想不明白key是方法的局部变量,怎么会同步呢,所以写了个测试类
package goodcenter.study;
import java.io.IOException;
public class TestSyString {
public void test(String str) throws InterruptedException{
String name = str;
synchronized(name){
Thread.sleep(5000);
System.out.println(name);
}
}
public static void main(String[] args) throws InterruptedException {
final TestSyString ts = new TestSyString();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
try {
ts.test("name");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
try {
ts.test("name");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thread1.start();
thread2.start();
Thread thread3 = new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);
String str = "name";
synchronized (str) {
System.out.println(str);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
thread3.start();
Thread.sleep(6000);
String str = "name";
// System.out.println(str);
try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
结果可以看到,居然thread3由于thread1或thread2同步阻塞了,为什么嗯
经过查询才知道,因为JVM有一种优化机制,因为String类型的对象是不可变的,因此当你使用""的形式引用字符串时,如果JVM发现内存已经有一个这样的对象,那么它就使用那个对象而不再生成一个新的String对象,这样是为了减小内存的使用,所以同步阻塞