与えられたコードに従って;
DATE_FORMATのインスタンスからの呼び出し形式メソッドは、DATE_FORMATのインスタンスにあるカレンダーオブジェクトを変更しているため、他のスレッドが印刷する前にカレンダーを修正する可能性があります(他のスレッドはカレンダーオブジェクトを変更したスレッドですが、まだ印刷されていません)。ここ
がSimpleDateFormat.class
// Called from Format after creating a FieldDelegate
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
calendar.setTime(date); // modifies the calender's instance
オーケーで参照され、しかしDATE_FORMATのロックはありませんDATE_FORMAT内のカレンダーを変更するには、他のスレッド を防ぐ必要がありますか? - @Santi
直接カレンダーを修正するために防止されていないが、2スレッドは1つのスレッドが待機しなければならない(DATE_FORMATのインスタンスである)同じ引数と同時に、同期ブロックを実行しようとすると、それは、DATE_FORMATのインスタンスにアクセス防止されます同期ブロックを実行する別のスレッド同期の仕組み
私はコメントで約束したように、私は私の答えを証明するためにシミュレーションを行いました。
private static DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
private static ArrayList<String> listDate = new ArrayList<>();
public static void doSomething()
{
for (int i = 0; i < 100; i++) {
final long msCurrentDate = i*100;
new Thread(new Runnable() {
public void run() {
synchronized (DATE_FORMAT) {
listDate.add(DATE_FORMAT.format(new Date(msCurrentDate)));
//System.out.println(DATE_FORMAT.format(Calendar.getInstance().getTime()));
}
}
}).start();
}
Runtime.getRuntime().addShutdownHook(new Thread()
{
@Override
public void run()
{
int resultSize = listDate.size();
System.out.println("All elements' size :" + resultSize);
resultSize = listDate.stream().distinct().collect(Collectors.toList()).size();
System.out.println("Unique elements' size :" + resultSize);
}
});
}
目的を変更せずにコードを修正しました。ご覧のとおり、同期されたバージョンと同期されていないバージョンのコードとの結果を比較するために、固定(スレッドごとに100msを増やす)時間を使用しています。
私はDatesを印刷しており、Look&Feelを比較するのではなく、数字を扱うStringのArrayListにDatesを追加しています。
まず私が印刷された結果を追加してみましょう:
![enter image description here](https://i.stack.imgur.com/U10x2.png)
左側に印刷された2複数の日があり、右側には何の複数日のコース最初の5つの結果の
はありません何も証明していない、あなたはそれらのすべてをチェックしなければならない。 だから私はここで、リストから
を同じエントリを削除した後、一覧と印刷結果に結果を追加した同期済みバージョンの結果である:ここで
//Output of all executions
//All elements' size :100
//Unique elements' size :100
は同期されていないバージョンの結果である:
//Output of execution : 1
//All elements' size :100
//Unique elements' size :82
//Output of execution : 2
//All elements' size :100
//Unique elements' size :78
//Output of execution : 3
//All elements' size :100
//Unique elements' size :81
結果によると、カレンダーはA、B、C ...の前にXスレッドによって変化していると言えるでしょう。リスト)
ストリームAPIを使用するにはJDK 8が必要です。また、他のコードを使用することもできます。私たちが議論できるようにご質問がありましたらお知らせください。
'' System.out.println''は、スレッドセーフであることが保証されていませんが、私はあなたのためにすべての問題が表示されません並行して呼び出すのではなく、同期アクセスを使用します。 –
実際ではない値が出力される可能性がありますか?たとえば、別のスレッドが印刷中に値を変更する可能性がありますか? (たとえそれがこのシナリオではないとしても) – Santi
おそらくインタビュアーがあなたの足を引っ張っていたかもしれません...私が見ている唯一の問題(私はこのケースでは問題として扱わない)は、スレッドが創造の秩序。タイムを取得し、その場でプリントするので、害はありません。 –