как узнать, является ли класс или метод java SE потокобезопасным?

наличие :

static private DateFormat df = new SimpleDateFormat();
public static void format(final Date date){ 
   for (int i=0;i<10;i++) 
     new Thread(new Runnable(){
         public void run(){
             System.out.println(df.format(date));
         } 
     });
}

класс DateFormat он задокументирован как не синхронизированный класс, но если мы используем только метод format, он не может изменить статус класса hole?

предположим, что он объявлен частным, как убедиться, что этот код является потокобезопасным ?

каков наилучший способ исправить этот код ?:

   1_ Using a different instance for every Thread.
   2_ Using a synchronized block.

3 ответов


  • для стандартного класса Java SE лучший способ узнать, является ли класс потокобезопасным, - внимательно прочитать его документацию. Всегда читайте документацию по классу и документацию по методу. Если вы говорите, что он не синхронизирован или не потокобезопасен, вы знаете, что он не потокобезопасен.
  • таким образом,DateFormat класс не потокобезопасным. В документации конкретно говорится:

    формат даты не синхронизированный. Рекомендуется создавать отдельные экземпляры формата для каждого потока. Если несколько потоков одновременно обращаются к формату, он должен быть синхронизирован извне.

  • объявление поля private тут не сделайте вашу реализацию потокобезопасной. private просто говорит, что внешние классы не могут видеть это поле. Давайте посмотрим на ваш метод:

     for (int i=0;i<10;i++) 
         new Thread(new Runnable(){
             public void run(){
                 System.out.println(df.format(date));
             } 
         });
    

    на Runnable объекты, которые вы создаете анонимные классы. Анонимные классы внутренний классы, которые имеют доступ к частным полям окружающего их класса. Если бы это было не так, ваша программа не компилировалась бы - они не могли получить доступ к


согласно документам, указано, что формат не является потокобезопасным.

синхронизация

форматы дат не синхронизированы. Рекомендуется создавать отдельные экземпляры формата для каждого потока. Если несколько потоков одновременно обращаются к формату, он должен быть синхронизирован извне.

дата в формате

Как это читать ? Если у вас нет явной гарантии, что какой-то метод потокобезопасный (или его документированный как небезопасный), то вы не можете делать никаких предположений о его безопасности.

однако, если вы действительно хотите использовать только один метод, который может быть неполным, вы всегда можете создать среду с высоким параллелизмом и проверить целостность данных с синхронизацией и без нее.

У меня был аналогичный вопрос к этому, с шифрами и RSA. Ответ там показывает один из способов, как проверить конкретный метод класса java SE в целом для этого. Однако, обратите внимание, эта реализация может измениться в любой момент, и, сделав свою собственную реализацию против деталей реализации, а не интерфейса, может вызвать некоторые непредсказуемые проблемы в будущем.

тестирование целостности данных


Я знаю, что в это трудно поверить, но DateFormat.format () фактически изменяет состояние DateFormat. Например, для SimpleDateFormat:

// 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);

здесь calendar является полем DateFormat.

поэтому я могу только рекомендовать вам доверять документации. Он может знать то, чего не знаешь ты.--3-->