由于SimpleDateFormat是一个非线程安全类(由于它的protected Calendar calendar;属性是非线程安全的),本来想测试下ThreadLocal下的线程安全SimpleDateFormat,结果输出的 simpleDateFormat 都是一样的
public class TestLocal {
ThreadLocal<SimpleDateFormat> threadLocal = new ThreadLocal<SimpleDateFormat>(){
@Override
protected SimpleDateFormat initialValue() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");
return simpleDateFormat;
}
};
@Test
public void testLocal(){
System.out.println(Thread.currentThread() + ",,," + threadLocal.get() + "");
new Thread(new Runn()).start();
}
class Runn implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread()+",,,"+threadLocal.get()+"");
}
}
}
输出:
new SimpleDateFormat
Thread[main,5,main],,,java.text.SimpleDateFormat@f2ac7da0
new SimpleDateFormat
Thread[Thread-0,5,main],,,java.text.SimpleDateFormat@f2ac7da0
当时我就震惊了 每个线程第一次get时候会调用initiaValue方法new一个
SimpleDateFormat对象(输出的
new SimpleDateFormat字符串证明确实new了) 怎么回输出相同的结果 发现是 由于
SimpleDateFormat 重写了 hashCode方法(调用了pattern属性的hashCode方法,pattern就是构造函数传进去的“yyyy-mm-dd hh:MM:ss”字符串),而toString调用了hashCode导致输出的结果不同
验证:
@Test
public void testEquals(){
String a=new String("aaa");
String b=new String("aaa");
System.out.println(a==b);
System.out.println(a.equals(b));
TestLocal testLocal = new TestLocal();
TestLocal testLocal2 = new TestLocal();
System.out.println(testLocal+",,,"+testLocal2);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(simpleDateFormat.hashCode());
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(simpleDateFormat2.hashCode());
System.out.println(simpleDateFormat2.equals(simpleDateFormat));
System.out.println(simpleDateFormat2==simpleDateFormat);
//simpleDateFormat2 重写了hashCode(调用 )方法 所以比较equals和hashcode是相同的 ==比较的是内存地址 所以不同
/*
1)对于==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
如果作用于引用类型的变量,则比较的是所指向的对象的地址
2)对于equals方法,注意:equals方法不能作用于基本数据类型的变量
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。
*/
}
输出:
false
true
threadLocal.TestLocal@64ab4d,,,threadLocal.TestLocal@12a55aa
1333195168
1333195168
true
false
SimpleDateFormat同步问题参考:http://www.cnblogs.com/peida/archive/2013/05/31/3070790.html
== 和 equals 和 hashCode参考:http://www.cnblogs.com/dolphin0520/p/3592500.html