【Java线程】SimpleDateFormat的线程安全性实验

【代码】

复制代码
package unsafesdf;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

public class Test {
    private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
    private static final int COUNT=100;
    private static final Executor exec=Executors.newFixedThreadPool(COUNT);
    
    public static void main(String[] args) throws Exception{
        Set<String> set=Collections.synchronizedSet(new HashSet<String>());
        CountDownLatch cdl=new CountDownLatch(COUNT);
        
        for(int i=0;i<COUNT;i++) {
            Calendar clder=Calendar.getInstance();
            final int ct=i;
            
            exec.execute(()->{
                clder.add(Calendar.DATE, ct);
                String dateStr=sdf.format(clder.getTime());
                set.add(dateStr);
                cdl.countDown();
            });
        }
        
        cdl.await();
        
        // 预期100,但实际小于100
        System.out.println(set.size());
    }
}
复制代码

【五次输出】

71

61

65

78

74

【原因】

SimpleDateFormat内部使用一个canlendat保存输入的时间,这在多线程环境里容易被后入线程所改写。

【参考资料】

《深入Java核心技术》张宏亮著 P390~391. 

END

posted @   逆火狂飙  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
历史上的今天:
2021-08-22 【oracle】常用表操作语句
2021-08-22 【oracle sql plus】清屏命令 clear screen
2021-08-22 【oracle】取余函数mod
2021-08-22 【Swing】使用lamda表达式简化事件响应的模板代码
2017-08-22 【Canvas与图标】对数图标 120*120
2013-08-22 【Canvas与函数极值】函数f(x)=((x+3)^2+1)^0.5+((x-5)^2+4)^0.5 的值域是?
生当作人杰 死亦为鬼雄 至今思项羽 不肯过江东
点击右上角即可分享
微信分享提示