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上,具体又说上不来,搞得我有点不淡定了。
所以来这里请教一下知道的人。

解决方案 »

  1.   

    唯一看到的是这个
    jetty-352
      

  2.   

    String常量和其他对象不同的地方,在于他的不可变性!而且同一个String值指向同一个对象,所以有可能会有很多用到同一个对象锁的,造成大面积的资源竞争……
    其他我就不知道了
      

  3.   

    因为String对象可重复的概率大造成死锁的几率大,貌似也是有道理的。不过这是在复杂的程序环境下才成立,因为无法全局掌控代码。
      

  4.   

    其实对于对象来说没有什么区别,只是一个直接调用构造函数创建对象,一个是通过反射来调用无参构造函数创建对象而已。从本质上来说也都是创建的新对象。就你上面的代码来说不是太有意义,那如果每个线程传入的都是新new的string的话,那就没办法锁了。
      

  5.   


    所以我标题说了,是对非new出来的String加锁。
      

  6.   

    send("zhangsan"); 
    这样用,会起到同步作用,是因为zhangsan是个字符常量,分布在数据区
    如果你这样用send(new String("zhangsan"));就不会同步,因为是在堆上分配的2个不同对象
    虽然值一样,所以进一步说明,锁定的是对象引用,而不是值