Java SImpleDateFormat线程安全问题
PHP中文网
PHP中文网 2017-04-17 17:31:32
0
3
524
public class Test {
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    private static class Task implements Runnable {

        public void run() {
            try {
                System.out.println(sdf.parse("2016-03-21 12:00:00").getTime());
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Task task = new Task();

        Thread t1 = new Thread(task);
        t1.start();
        Thread t2 = new Thread(task);
        t2.start();
        Thread t3 = new Thread(task);
        t3.start();
        Thread t4 = new Thread(task);
        t4.start();
        Thread t5 = new Thread(task);
        t5.start();
    }
}

最近才知道,如果像上面代码那样通过定义静态共享的实例来使用SimpleDateFormat是会存在线程安全问题的。

例如线程被挂死:

或者转换的时间不对:

然后自己尝试读JDK源码来试图分析在SimpleDateFormat的代码中,究竟是哪里的函数或者代码会引起线程不安全,但是由于水平有限,最后还是找不出。

哪位大牛可以帮忙分析一下。

PS:我的jdk版本:1.8.0_73

PHP中文网
PHP中文网

认证高级PHP讲师

全員に返信(3)
左手右手慢动作

parse() ソース コードのコメントを見てみると、この人が書いたセクションがありました

この解析操作では、{@link DateFormat#calendar

が使用されます
  • calendar} を使用して {@code Date} を生成します。すべての {@code

  • calendar} の日時フィールドは {@linkplain Calendar#clear()

  • です 解析前に
  • cleared}、および {@code Calendar} のデフォルト

  • 日時フィールドの値は、欠落している

  • に使用されます。
  • 日時情報。

一般的な意味は、parse() メソッドがカレンダーを使用して返される Date インスタンスを生成するということです。問題は、ここで使用されるカレンダーが、メソッドが実行されるたびに新しいものではないということです。これは、「保護されたカレンダー」カレンダーを定義します。コメントの意味によると、各解析の前に、カレンダー内の関連する属性がクリアされ、その後、オブジェクトに新しい処理結果が書き込まれます。この場合、マルチスレッドでは、 parse() を実行すると、カレンダーを設定した後、別のスレッドがそれをクリアします。これにより、他の問題が発生するはずです。

いいねを押す +0
Ty80

リーリー

ここで使用されているカレンダーはクラスメンバーであり、マルチスレッドの setTime はスレッドの安全性の問題を引き起こします

いいねを押す +0
伊谢尔伦

これは SimpleDateFormat の実装とは何の関係もありません。複数のスレッドで同じオブジェクトを使用し、スレッドの同期に失敗することに関係しています。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート