SimpleDateFormat的测试,此类不是线程安全的。

本文通过一个多线程环境下的测试案例,展示了Java中SimpleDateFormat类并非线程安全,并提供了两种解决方案:使用局部变量或ThreadLocal。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SimpleDateFormat这个类,大部分都可能认为是线程安全,或者更本没有想线程不线程的问题。

 

测试代码:(测试的时候也会有异常抛出,我代码中catch了)

 

[c-sharp]  view plain copy
  1. public class SimpleDateFormatTest extends Thread {  
  2.     // 时间  
  3.     private static String dateString = "2010-10-01 02:10:9";  
  4.     // 加入元素  
  5.     private static Set<Long> set = Collections.synchronizedSet(new HashSet<Long>());  
  6.     // 控制线程退出  
  7.     private static AtomicBoolean ok = new AtomicBoolean(true);  
  8.     // 每个线程一个SimpleDateFormat  
  9.     // static ThreadLocal<SimpleDateFormat> format = new  
  10.     // ThreadLocal<SimpleDateFormat>() {  
  11.     // protected SimpleDateFormat initialValue() {  
  12.     // SimpleDateFormat format = new SimpleDateFormat();  
  13.     // format.applyPattern("yyyy-MM-dd HH:mm:ss");  
  14.     // return format;  
  15.     // }  
  16.     // };  
  17.     private static SimpleDateFormat format;  
  18.     static {  
  19.         format = new SimpleDateFormat();  
  20.         format.applyPattern("yyyy-MM-dd HH:mm:ss");  
  21.     }  
  22.     public void run() {  
  23.         while (SimpleDateFormatTest.ok.get()) {  
  24.             try {  
  25.                 set.add(((Date) SimpleDateFormatTest.format  
  26.                         .parseObject(dateString)).getTime());  
  27.             } catch (Exception e) {  
  28.                 // e.printStackTrace();  
  29.             }  
  30.         }  
  31.     }  
  32.     public static void main(String args[]) throws ParseException,  
  33.             InterruptedException {  
  34.         // 定义线程池  
  35.         ExecutorService pools = Executors.newCachedThreadPool();  
  36.         // 加入判断逻辑  
  37.         pools.execute(new Runnable() {  
  38.             public void run() {  
  39.                 try {  
  40.                     while (SimpleDateFormatTest.ok.get()) {  
  41.                         if (SimpleDateFormatTest.set.size() > 2) {  
  42.                             System.out.println("size"+SimpleDateFormatTest.set.size());  
  43.                             SimpleDateFormatTest.ok.set(false);  
  44.                             System.out.println("check error");  
  45.                         }  
  46.                         Thread.sleep(1000);  
  47.                     }  
  48.                 } catch (InterruptedException e) {  
  49.                     e.printStackTrace();  
  50.                 }  
  51.             }  
  52.         });  
  53.         // 加入线程  2个  
  54.         for (int i = 0; i < 2; i++) {  
  55.             pools.execute(new SimpleDateFormatTest());  
  56.         }  
  57.         // 设置时间  
  58.         pools.execute(new Runnable() {  
  59.             @Override  
  60.             public void run() {  
  61.                 int i = 0;  
  62.                 try {  
  63.                     while (i++ < 10 && SimpleDateFormatTest.ok.get()) {  
  64.                         System.out.println("check " + i + "s");  
  65.                         Thread.sleep(1000);  
  66.                     }  
  67.                     if (SimpleDateFormatTest.ok.get()) {  
  68.                         SimpleDateFormatTest.ok.set(false);  
  69.                         System.out.println("check ok");  
  70.                     }  
  71.                 } catch (InterruptedException e) {  
  72.                     e.printStackTrace();  
  73.                 }  
  74.             }  
  75.         });  
  76.         pools.shutdown();  
  77.     }  
  78. }  
 

运行报错:

 

check 1s

size1598

check error

 

所以在多线程的环境中,要么用局部变量;要么ThreadLocal,但是这个又不好控制,所以建议 直接局部变量吧!

 

  1. static ThreadLocal<SimpleDateFormat> format = new  
  2. ThreadLocal<SimpleDateFormat>() {  
  3. protected SimpleDateFormat initialValue() {  
  4. SimpleDateFormat format = new SimpleDateFormat();  
  5. format.applyPattern("yyyy-MM-dd HH:mm:ss");  
  6. return format;  
  7. }  
  8. };  

转:http://blog.youkuaiyun.com/bxyz1203/article/details/6056333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值