2017-01-04 3 views
1

Я пишу свой код на Java, где я создаю объект и получаю его в двух разных потоках. Мой первый поток thread1 вызывает некоторые общедоступные методы для этого объекта во время выполнения.Проверка того, что объект имеет значение null в Java

final Thread thread1 = new Thread(){ 
    @Override 
    public void run() { 
     myObj.pubFunc1(); 
     myObj.puFunc2(); 
     myObj.pubFunc3(); 
    } 
}; 

У меня есть еще один поток thread2 который может освободить этот объект и установить его в null как:

final Thread thread2 = new Thread(){ 
    @Override 
    public void run() { 
     myObj.release(); 
     myObj = null; 
    } 
}; 

Мой вопрос, если я должен поставить проверить null вокруг каждого оператора в моем thread1, как это?

final Thread thread1 = new Thread(){ 
     @Override 
     public void run() { 
      if(myObj != null) { 
       myObj.pubFunc1(); 
      } 
      if(myObj != null) { 
       myObj.pubFunc2(); 
      } 
      if(myObj != null) { 
       myObj.pubFunc3(); 
      } 
     } 
    }; 

ИЛИ достаточно одной проверки всех утверждений? Основной вопрос, который может возникнуть из этого, заключается в блокировке объекта, на котором мы сделали нулевую проверку? Как справиться с этой ситуацией. Какой шаблон проектирования следует использовать для обработки этой ситуации.

ПРИМЕЧАНИЕ: Я не хочу, чтобы три утверждения выполнялись обязательно, и я даже не хочу, чтобы эти три утверждения составляли атомную единицу. Я просто хочу выполнить операцию, если объект, который я выполняю операцию, не является нулевым.

+3

Если объект может стать асинхронным, необходимо его проверить, и он должен быть либо «volatile», либо прочитан и написан только в «синхронизированных» блоках или методах. Это не «шаблон дизайна», это просто здравый смысл, возникающий из JLS. – EJP

ответ

3

Дизайн вашего предложения ошибочен. Представьте себе, это исполнение:

  • myObj = new MyObject();
  • Тема 2: if (myObjec != null) => все хорошо, объект не является нулевым
  • Тема 1: myObj.release(); myObj = null;
  • Тема 2: myObj.pubFunc1(); => Boom, NPE.

Я думаю, что у вас есть только 2 варианта:

  • либо вы синхронизируют доступы к myObj, чтобы сделать, если/pubFunc вызывает атомное
  • или сохранить локальную копию объекта - это может или не может быть приемлемым в зависимости от вашего случая использования:

    public void run() { 
        MyObject localObj = myObj; 
        if (localObj != null { //NOTE: myObj may have been released 
        localObj.pubFunc1(); 
        localObj.puFunc2(); 
        localObj.pubFunc3(); 
        } 
    } 
    

Примечание. Я предполагаю, что вы знаете о проблемах видимости и что myObj правильно опубликован/синхронизирован.

+0

Я понимаю смысл синхронизируемого объекта. Что именно вы подразумеваете под «публикацией». Кроме того, я предполагаю, что, когда вы говорите «проблемы видимости», это связано с личными, общественными, защищенными и видимыми уровнями на уровне пакетов? – Swapnil

+0

@Swapnil no Я имел в виду видимость по потокам. Например, я полагаю, что либо 'myObj' будет полностью создан до начала потоков, либо будет изменчивым. И я также предположил, что различные методы (pubFunc1 и т. Д.) Являются потокобезопасными. – assylias

+0

Итак, до сих пор я понимаю, что вы предлагаете иметь проверку «null» и все три вызова функции внутри synchronizedmy (Obj) (которые также должны быть окружены нулевой проверкой).И когда вы говорите, что методы являются потокобезопасными, вы имеете в виду, что у них есть ключевое слово 'synchronized' с их объявлениями? – Swapnil