2017-01-13 11 views
2

Я наткнулся на этот метод в проекте, над которым я работаю, и сразу подумал, что что-то не так. У меня было ощущение, что это не может быть ничем иным.Вложенные 'synchronize': как этот синхронизированный метод Java будет реорганизован - и может ли это иметь какой-то смысл?

Но я не понимаю намерений и последствий этого. Может ли это быть реорганизовано? Обеспечивает ли вторая синхронизация какой-либо смысл - и не является третьим синхронизированным избыточным/ненужным?

Я только начинаю работать в расширенном параллельном/потоковом программировании в java - подробное объяснение, почему это имеет смысл или нет смысла и почему очень ценится!

@Override 
    public synchronized void run() { 
     synchronized (this.market) { 
      synchronized (this.market.getWallet()) { 
       this.handler.handleEvent(new WalletLecherEvent(this, market, 
         market.leechWallet())); 
      } 
     } 
    } 

заранее спасибо

редактировать, для того чтобы поставить больше контекста:

public class WalletLeecherWorker extends Worker { 
     private IAbstractMarketAPI market = null; 

     private Thread thread = null; 

     public WalletLeecherWorker(IEventHandler handler, IAbstractMarketAPI market) { 
      super(handler); 
      this.market = market; 
     } 

     public void startThread() { 
      if (thread != null) 
       return; 

      thread = new Thread(this); 
      thread.start(); 
     } 

     public MARKETs getMarket() { 
      return this.market.getName(); 
     } 

     @Override 
     public synchronized void run() { 
      synchronized (this.market) { 
       synchronized (this.market.getWallet()) { 
        this.handler.handleEvent(new WalletLecherEvent(this, market, 
          market.leechWallet())); 
       } 
      } 
     } 
    } 

..и метод market.getWallet():

@Override 
public Wallet getWallet() { 
    return this.wallet; 
} 

Я думать, что чем цель состоит в том, чтобы заблокировать все потоки от старый Кошельки, поэтому невосприимчиво синхронизированы/устарели данные - до тех пор, пока этот поток работает();

+1

Ни один из ваших вопросов не подлежит обсуждению без дополнительного контекста. Это зависит от того, кто еще имеет доступ к этим ценностям и каким образом. – shmosel

+0

Я понимаю @shmosel, но разве это не вызывает повышенного подозрения? Вторая синхронизированная синхронизация доступа к this.market - следующий код синхронизирует доступ к методу одного и того же объекта - разве это не избыточно? Я добавлю еще несколько контекстов. – Gewure

+1

Подозрительный? Да. Неправильно? Я не могу сказать. – shmosel

ответ

2

код получает блокировку на следующих объектах:

  • this - Предотвращает несколько потоков от вызова run() на том же WalletLeecherWorker например
  • this.market - Предотвращает run() от производства, если другой поток получил блокировку на котором это разумное предположение, учитывая, что экземпляр market, вероятно, разделен
  • this.market.wallet - аналогично предыдущему

Ничего из этого, очевидно, не нужно, за исключением того, что синхронизированный метод run(). Он не обеспечивает защиту, кроме того, что делает следующий синхронизированный блок. Сам код может быть из-за использования очень мелкой зернистой блокировки, причем этот конкретный код должен блокировать все, тогда как другой код может блокировать только кошелек, рынок и кошелек.

Однако этот код может представлять собой ошибку (и даже тупик). Если вы заблокируете объекты в неправильном порядке, вы можете зайти в тупик. Это также не очень читаемо, как вы видите. Также сомнительно иметь Thread в качестве переменной экземпляра класса с помощью метода startThread(). Код не может быть сломан, но это, конечно, не очень красиво.

+1

Там теоретически может быть метод, который заменяет «рынок», делая внешнюю синхронизацию еще необходимой. – shmosel

+0

очень симпатичный информация. Действительно, рынок-экземпляр разделяется. Итак, «синхронизированный» перед run(), вероятно, будет избыточным? – Gewure

+1

@shmosel В теории да, но я в этом сомневаюсь. Этот код выглядит как асинхронная задача с менее оптимальной реализацией. Вид, который, если бы он был написан с помощью текущих инструментов, вы использовали бы «Executor» и улучшенные примитивы параллелизма, поэтому у вас не было бы никаких «синхронизированных» блоков в коде. – Kayaman

Смежные вопросы