日期:2014-05-20  浏览次数:20840 次

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(){ ……
觉得说得很有道理啊