System.out.println("线程[" + Thread.currentThread().getName() + "]指定日期为[" + timeStr + "], " +
"经过幸苦的计算后, 得到的天数为[" + day + "], 得到的月份为[" + (month + 1) + "月]");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
最后是程序的入口
[java]
public class StaticTest {
public static void main(String[] args) {
TestStaticThread testStaticThread1 = new TestStaticThread("2013-02-05 15:15:15");
TestStaticThread testStaticThread2 = new TestStaticThread("2013-04-10 18:45:30");
TestStaticThread testStaticThread3 = new TestStaticThread("2013-06-15 18:45:30");
Thread t1 = new Thread(testStaticThread1, "t1");
Thread t2 = new Thread(testStaticThread2, "t2");
Thread t3 = new Thread(testStaticThread3, "t3");
t1.start();
t2.start();
t3.start();
}
}
public class StaticTest {
public static void main(String[] args) {
TestStaticThread testStaticThread1 = new TestStaticThread("2013-02-05 15:15:15");
TestStaticThread testStaticThread2 = new TestStaticThread("2013-04-10 18:45:30");
TestStaticThread testStaticThread3 = new TestStaticThread("2013-06-15 18:45:30");
Thread t1 = new Thread(testStaticThread1, "t1");
Thread t2 = new Thread(testStaticThread2, "t2");
Thread t3 = new Thread(testStaticThread3, "t3");
t1.start();
t2.start();
t3.start();
}
}
很明显,上面的getDay()和getMonth()是有问题的!什么?你说你不相信?好吧就让结果来说明问题!
[java]
线程[t2]指定日期为[2013-04-10 18:45:30], 经过幸苦的计算后, 得到的天数为[36], 得到的月份为[2月]
线程[t1]指定日期为[2013-02-05 15:15:15], 经过幸苦的计算后, 得到的天数为[36], 得到的月份为[2月]
线程[t3]指定日期为[2013-06-15 18:45:30], 经过幸苦的计算后, 得到的天数为[166], 得到的月份为[6月]
Process finished with exit code 0
线程[t2]指定日期为[2013-04-10 18:45:30], 经过幸苦的计算后, 得到的天数为[36], 得到的月份为[2月]
线程[t1]指定日期为[2013-02-05 15:15:15], 经过幸苦的计算后, 得到的天数为[36], 得到的月份为[2月]
线程[t3]指定日期为[2013-06-15 18:45:30], 经过幸苦的计算后, 得到的天数为[166], 得到的月份为[6月]
Process finished with exit code 0
哈哈,果断错了有木有!!
那么,要改正很简单,有两种方法:
1、把getDay()和getMonth()设置成同步方法,即改成如下
[html]
public static synchronized int getDay(Date date)
public static synchronized int getMonth(Date date)
public static synchronized int getDay(Date date)
public static synchronized int getMonth(Date date)
2、把上面声明的calendar放到方法体内,即如下所示
[java]
public static int getDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_YEAR);
}
public static synchronized int getMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.MONTH);
}
public static int getDay(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.DAY_OF_YEAR);
}
public static synchronized int getMonth(Date date) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar.get(Calendar.MONTH);
}
但是第一种方法其实还是存在问题的,由于静态锁锁的是这个Class,并不是锁Object,所以如果程序别处用TimeUtile tu = new TimeUtil() 去实例化一个对象,然后一个线程去调用getDay()(用TimeUtil.getDay()),另一线程调用getMonth()(用tu.getMonth() 此处需要把getMonth()改成非静态方法,如果是静态方法是安全的!),其实还是会出现问题的!当然,我们可以重写这个类的构造方法,禁止实例化来