String对象作为同步锁遇到的有关问题

String对象作为同步锁遇到的问题
这个程序有100个线程,每个线程都对一个值进行加二操作,但"加二"这个行为是同步的,互不干涉(即其他线程会出现阻塞,等待释放锁),所以控制台只会输出偶数.如果出现干涉,就会输出奇数信息.

这个同步方式是使用同步代码块,对字符串对象进行加锁.
synchronized(key){/*some code*/}


但问题出现了:
String key = "key_for_add";


String key = new String("key_for_add");

作为同步锁有什么不同?为什么前者不会产生干涉?后者会有干涉,出现奇数很好理解,因为每个线程锁定的都是不同的String对象


以下是详细代码:
public class ExecutorsDemo2{

private int currentEvenValue = 0;
private String defaultKey;

public ExecutorsDemo2(String key){
this.defaultKey = key;
}

public static void main(String[] args){

ExecutorsDemo2 ed = new ExecutorsDemo2("key1");
ExecutorService exec = Executors.newCachedThreadPool();
for(int i=0;i<100;i++){
exec.execute(new AddTask(ed));
}
exec.shutdown();

}

public void add(String skey){

String key = skey;                            //同步
//String key = "key_for_add";                            //同步,为什么?
//String key = new String("key_for_add");                            //不同步,出现奇数
//String key = skey + "_for_add";                            //不同步,出现奇数
//String key = new StringBuilder(skey).toString();  //不同步,出现奇数
//String key = new StringBuilder(skey).append("_for_add").toString();  //不同步,出现奇数

synchronized(key){
this.currentEvenValue++;
Thread.yield();
this.currentEvenValue++;
int result = currentEvenValue;
if(result%2!=0){
System.out.println("*** error : value is "+result);
}else{
System.out.println("value is "+currentEvenValue);
}
}
}

public String getActionKey(){
return this.actionKey;
}

}


public class AddTask implements Runnable{

public ExecutorsDemo2 ed;

public AddTask(ExecutorsDemo2 ed){
this.ed = ed;
}

public void run() {
ed.add(ed.getActionKey());
}

}


至于我为什么不用同步方法或锁其他对象,可以看这里:http://www.cnblogs.com/mushroom/p/4199701.html
------解决思路----------------------
String是final类,每次使用+或者new之后都会在内存中创建新的String对象,而如果String=常量时,String常量存在常量池中,不会重新创建,所以在你的栗子中,那个String其实每次都不一样,导致加锁失败。fyi。