我们可以将SimpleDateFormat对象声明为静态对象

Joe*_*Joe 19 java thread-safety simpledateformat

SimpleDateFormat monthFormat = new SimpleDateFormat("MMMM");
SimpleDateFormat fullFormat = new SimpleDateFormat("EE MMM dd, HH:mm:ss")
Run Code Online (Sandbox Code Playgroud)

我有几个这样的代码经常被调用,将它们声明为static变量是否有意义?

format()在这种情况下,将动态参数传递给方法是否安全?

Jig*_*shi 29

不,它们不是线程安全的.请使用Joda-time的版本 .

或者将它们包装在synchronized方法中并使其成为线程安全的

Doc清楚地说

日期格式未同步.建议为每个线程创建单独的格式实例.如果多个线程同时访问格式,则必须在外部进行同步.

  • 在我看来,同步是一种非常次优的方式.关键部分应始终是您的最后手段,仅用于必须全局唯一且线程安全的对象.使用ThreadLocal.为每个新线程创建一次SimpleDateFormat的成本将在性能和复杂性方面可靠地超过同步成本. (3认同)
  • 我通常使用`ThreadLocal`和`SimpleDateFormat` (2认同)
  • 大多数开发人员都明白,对于大多数不是线程安全的类,这是由于同时更改状态造成的。一旦建立了格式,格式化日期不应改变状态。简单地在官方文档中将其记录为非线程安全是不够的。应该明确记录,如果格式方法在实例变量中保持临时状态,则它也不是线程安全的。将其声明为静态不仅仅是一个新手错误。可以在修改集合 (put) 与访问集合 (get) 之间进行类比。 (2认同)

Mag*_*lex 18

从Java 8开始,新的Date API支持此功能.DateTimeFormatter是线程安全的,可以做同样的工作SimpleDateFormat.引自JavaDoc:

从模式创建的格式化程序可以根据需要多次使用,它是不可变的并且是线程安全的.

更清楚的是,定义一个格式是完全正确的,例如:

private static DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
Run Code Online (Sandbox Code Playgroud)

并在可以由多个线程同时访问的方法中使用它:

String text = date.toString(formatter);
LocalDate date = LocalDate.parse(text, formatter);
Run Code Online (Sandbox Code Playgroud)