Java对非new出来的String进行加锁,有什么潜在的问题没有?
public class Test {
public static void main(String[] args) {
new Thread(){
public void run(){
send("zhangsan");
}
}.start();
new Thread(){
public void run(){
send("zhangsan");
}
}.start();
new Thread(){
public void run(){
send("lisi");
}
}.start();
}
public static void send(String name){
synchronized (name) {
System.out.println(Thread.currentThread().getName() + "," + name);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
目前自己测试了一把,可以测出“zhangsan”因为被加锁所以第二个线程只能5秒后才处理。
没有发现什么问题,可以满足我的需求。
但听一朋友说java对String加锁有什么潜在的bug,还被sun列在bug list上,具体又说上不来,搞得我有点不淡定了。
所以来这里请教一下知道的人。
------解决方案-------------------- 貌似没听说过,应该没啥区别的
------解决方案-------------------- 等解。。。。。
------解决方案-------------------- 唯一看到的是这个
jetty-352
------解决方案-------------------- 引用: Java code?1234567891011121314151617181920212223242526272829303132public class Test { public static void main(String[] args) { new Thread(){ public void run(){ ……
String常量和其他对象不同的地方,在于他的不可变性!而且同一个String值指向同一个对象,所以有可能会有很多用到同一个对象锁的,造成大面积的资源竞争……
其他我就不知道了
------解决方案-------------------- 引用: 唯一看到的是这个
jetty-352
因为String对象可重复的概率大造成死锁的几率大,貌似也是有道理的。不过这是在复杂的程序环境下才成立,因为无法全局掌控代码。
------解决方案-------------------- 其实对于对象来说没有什么区别,只是一个直接调用构造函数创建对象,一个是通过反射来调用无参构造函数创建对象而已。从本质上来说也都是创建的新对象。就你上面的代码来说不是太有意义,那如果每个线程传入的都是新new的string的话,那就没办法锁了。
------解决方案-------------------- 用Test.class 百无禁忌了,
------解决方案-------------------- send("zhangsan");
这样用,会起到同步作用,是因为zhangsan是个字符常量,分布在数据区
如果你这样用send(new String("zhangsan"));就不会同步,因为是在堆上分配的2个不同对象
虽然值一样,所以进一步说明,锁定的是对象引用,而不是值
------解决方案-------------------- ------解决方案-------------------- 引用: 引用:
Java code?1234567891011121314151617181920212223242526272829303132public class Test { public static void main(String[] args) { new Thread(){ public void run(){ …… 觉得说得很有道理啊