在SimpleDateFormat和克隆上同步

Sur*_*ran 15 java clone date-format thread-safety

我们知道dateformat类不是线程安全的.我有一个多线程场景,需要使用dateformats.我无法在新线程中创建新实例,因为SimpledateFormat创建似乎很昂贵(构造函数最终调用"编译",这是昂贵的).经过一些测试,我只剩下两个选项:

  1. 外部同步 - 我真的不想这样做
  2. 克隆每个线程 - 不知道是否有一些捕获?

有什么建议?

如果大家之前已经面对过这个问题,你会采取什么方向.

注意:之前曾问过一个类似的问题,但它被关闭指向一个apache包.我不能为此使用新库.我也在SO上读过这个类似的问题

Law*_*Dol 13

如果您创建了一个类,它将使用固定大小的预先创建的SimpleDateFormat对象池以循环方式格式化日期?鉴于无争议的同步很便宜,这可以在SimpleDateFormat对象上同步,从而在整个集合中分摊冲突.

因此,可能有50个格式化程序,每个格式化程序轮流使用 - 因此只有当51个日期实际同时格式化时才会发生锁争用.

编辑2011-02-19(太平洋标准时间)

我按照上面的建议实现了一个固定池,我的网站上提供了代码(包括测试).

以下是在Java 6 SE客户端JVM中运行的四核AMD Phenom II 965 BE的结果:

2011-02-19 15:28:13.039 : Threads=10, Iterations=1,000,000
2011-02-19 15:28:13.039 : Test 1:
2011-02-19 15:28:25.450 :   Sync      : 12,411 ms
2011-02-19 15:28:37.380 :   Create    : 10,862 ms
2011-02-19 15:28:42.673 :   Clone     : 4,221 ms
2011-02-19 15:28:47.842 :   Pool      : 4,097 ms
2011-02-19 15:28:48.915 : Test 2:
2011-02-19 15:29:00.099 :   Sync      : 11,184 ms
2011-02-19 15:29:11.685 :   Create    : 10,536 ms
2011-02-19 15:29:16.930 :   Clone     : 4,184 ms
2011-02-19 15:29:21.970 :   Pool      : 3,969 ms
2011-02-19 15:29:23.038 : Test 3:
2011-02-19 15:29:33.915 :   Sync      : 10,877 ms
2011-02-19 15:29:45.180 :   Create    : 10,195 ms
2011-02-19 15:29:50.320 :   Clone     : 4,067 ms
2011-02-19 15:29:55.403 :   Pool      : 4,013 ms
Run Code Online (Sandbox Code Playgroud)

值得注意的是,克隆和汇集非常紧密.在重复运行中,克隆速度快于汇集速度,因为它的速度较慢.当然,这项测试是为极端争用而刻意设计的.

在SimpleDateFormat的特定情况下,我想我可能只想创建一个模板并按需克隆它.在更一般的情况下,我可能会试图将此池用于此类事情.

在以某种方式做出最终决定之前,我想彻底测试各种JVM,版本以及各种这些对象.较旧的JVM以及手持设备和手机等小型设备上的JVM可能会在对象创建和垃圾收集方面产生更多开销.相反,它们可能在无争议的同步中有更多的开销.

FWIW,从我对代码的回顾来看,似乎SimpleDateFormat很可能在克隆时做的工作量最大.

编辑2011-02-19(太平洋标准时间)

同样有趣的是无竞争的单线程结果.在这种情况下,池与单个同步对象相同.这意味着该池是整体上最好的替代方案,因为它在满足和无条件时提供出色的性能.有点令人惊讶的是单线程克隆不太好.

2011-02-20 13:26:58.169 : Threads=1, Iterations=10,000,000
2011-02-20 13:26:58.169 : Test 1:
2011-02-20 13:27:07.193 :   Sync      : 9,024 ms
2011-02-20 13:27:40.320 :   Create    : 32,060 ms
2011-02-20 13:27:53.777 :   Clone     : 12,388 ms
2011-02-20 13:28:02.286 :   Pool      : 7,440 ms
2011-02-20 13:28:03.354 : Test 2:
2011-02-20 13:28:10.777 :   Sync      : 7,423 ms
2011-02-20 13:28:43.774 :   Create    : 31,931 ms
2011-02-20 13:28:57.244 :   Clone     : 12,400 ms
2011-02-20 13:29:05.734 :   Pool      : 7,417 ms
2011-02-20 13:29:06.802 : Test 3:
2011-02-20 13:29:14.233 :   Sync      : 7,431 ms
2011-02-20 13:29:47.117 :   Create    : 31,816 ms
2011-02-20 13:30:00.567 :   Clone     : 12,382 ms
2011-02-20 13:30:09.079 :   Pool      : 7,444 ms
Run Code Online (Sandbox Code Playgroud)