В соответствии с данным кодом;
Метод форматирования вызова из экземпляра DATE_FORMAT модифицирует объект каландра, который находится в экземпляре DATE_FORMAT, поэтому его возможный 1 поток может изменять каландр перед другими отпечатками потоков (другой поток - это поток, который изменил объект календаря, но он не печать еще).
здесь ссылка в 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
Это не препятствует, чтобы изменить календарь непосредственно, но предотвращение доступа к экземпляру date_format, в случае, если 2 потока пытается выполнить синхронизированный блок одновременно с тем же аргументом (который является экземпляром date_format в) 1 поток должен ждать другой - выполнить этот синхронизированный блок. Вот как работает синхронизация.
Теперь, как я обещал в комментарии, я сделал симуляцию, чтобы доказать свой ответ.
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);
}
});
}
Я изменил данный код, не изменяя его цель. Как вы можете видеть, я использую фиксированное (и увеличивающееся 100 мс для потока) время для сравнения результатов с синхронизированными и несинхронизированными версиями кода.
Я печатаю даты, а также добавляю Даты в ArrayList String для работы с числами, а не просто для сравнения и сравнения.
Прежде всего позвольте мне добавить распечатанные результаты:
На левой стороне есть 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
Согласно результатам, мы можем сказать, что календарь изменяется по потоку X до тех пор, пока A, B, C ... нити не распечатывают дату (или добавляют к список)
Вы можете протестировать и увидеть его сами, для отличного результата вам нужен JDK 8 для использования потоков api или вы можете использовать любой другой код. Пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы, чтобы мы могли спорить.
'' System.out.println'' не гарантирован поточно, но я не вижу никакой проблемы, потому что вы «не вызывать его параллельно, а использовать синхронизированный доступ. –
Вы имеете в виду, что он может печатать недействительное значение? Например, другой поток может изменить значение при печати? (Даже если это не такой сценарий) – Santi
Возможно, интервьюер тянул вашу ногу ... Единственная проблема, которую я вижу (которую я даже не рассматриваю как проблему в этом случае) заключается в том, что нити не гарантируются в порядок создания. Время набирается и печатается «на лету», поэтому никакого вреда не делается. –