Java-SimpleDateFormat线程不安全?

发布于 2017-01-13 06:38:15 字数 53 浏览 1250 评论 4

Java里的SimpleDateFormat是线程不安全的,具体是怎样不安全呢?举个例子。。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

晚风撩人 2017-08-18 03:02:00

每个类线程是否安全,要是都要通过代码测试,那么Oracle的开发人员恐怕是要累死了.多看看SimpleDateFormat源码吧.这个类有好几个的状态值,而且这些状态没有受到任何安全机制的保护.有些状态还是static的,所以要想做同步,加threadlocal是不合适的,只能使用线程同步"监视器"模式.对于这样一个工具栏,使用这个模式,显然是没必要的.

验证不同步的办法很简单,随便找一个函数就行了,而且代码也没几行

public class MainTest {
private final static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd");
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) {
Task t1=new Task("2007-9-20");
Task t2=new Task("2008-6-30");
new Thread(t1).start();
new Thread(t2).start();

}

private static void p(Object o){
System.out.println("thread id= "+Thread.currentThread().getId()+" : "+o);
}

private static class Task implements Runnable{
private String pattern;
private Task(String pattern){
this.pattern=pattern;
}
@Override
public void run() {
for(int i=0;i<20;i++){
try {
Date date = simpleDateFormat.parse(pattern);
p(date.toString());
} catch (Exception e) {
p(e);
}
}
}
}
}

小noe明白了吧

代码要格式化哦,edit by 斑驳 (ps: 俺叫 neo)

晚风撩人 2017-08-12 17:21:15

做了很简单的实验, 就是两个线程同时去parse同一个simpledateformat.
实验结果表明, 在sun jre1.5上, simpledateformat内部状态完全混乱了.
但是, 在sun jre1.6和1.7上没有看到类似的问题.

晚风撩人 2017-07-12 17:34:18

你的那个质疑是没有必要的,因为这个类并不是什么线程不安全的。

官方中文大意:

日期格式(Date format)是不同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的。

不能说线程安全与否与是否被同步是直接关系,更重要的是,与这个类没啥关系,是日期格式。

祝好,
斑驳敬上

虐人心 2017-07-02 17:10:19

的确是线程不安全的
看代码吧

import java.io.*;
import java.lang.Thread;
import java.text.SimpleDateFormat;
import java.util.Date;

class R1 implements Runnable{
private SimpleDateFormat fmt;
private Date date;

public R1(SimpleDateFormat fmt,Date date){
this.fmt = fmt;
this.date = date;
}
public void run(){
for(;;){
try{
Date d = fmt.parse("2012-12-24");
}catch(Exception e){
System.out.println(fmt.format(date));
}
}
}
}

class R2 implements Runnable{
private SimpleDateFormat fmt;
private Date date;

public R2(SimpleDateFormat fmt,Date date){
this.fmt = fmt;
this.date = date;
}
public void run(){
for(;;){
try{
Date d = fmt.parse("2012-12-25");
}catch(Exception e){
System.out.println(fmt.format(date));
}
}
}
}

public class ddd {
public static void main(String[] args) throws Exception{
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd");
Date d1 = new Date();
Date d2 = new Date(d1.getTime()+(1000L*3600L*24L));
R1 r1 = new R1(fmt,d1);
R2 r2 = new R2(fmt,d2);
System.out.println(fmt.format(d1));
System.out.println(fmt.format(d2));
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文