Подтвердить что ты не робот

Можно ли использовать метод ядовитых таблеток с ограниченными очередями?

В Java Concurrency В книге "Практика" (стр. 156) есть выражение относительно подхода к ядовитой таблетке:

Ядовитые таблетки работают надежно только с несвязанными очередями.

Означает ли это, что с ограниченной очередью я могу зайти в тупик, или это касается некоторых других проблем с живучестью? Связано ли это с количеством производителей и клиентов?

4b9b3361

Ответ 1

С ограниченной очередью вам может быть запрещено добавлять ядовитую таблетку.

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

Ответ 2

Проблема заключается в том, что очередь может быть заполнена в сжатые сроки.

Это зависит от того, насколько ценны данные в очереди во время закрытия. Можете ли вы позволить себе бросить все в очереди?

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

void close () throws InterruptedException {
  do {
    // Empty the queue.
    while ( queue.poll(0,TimeUnit.MILLISECONDS) != null ) {
      // Throw it away.
    }
    // Keep draining the queue 'till the pill is swallowed.
  } while (!queue.offer(STOP, 0, TimeUnit.MILLISECONDS)) ;
}

но, конечно, если элементы в очереди ценны, вы можете использовать drainto и сохранять их.

Пожалуйста, имейте в виду, что после ядовитой таблетки может быть добавлено больше предметов, потому что не только очередь может быть заполнена, но также могут быть заблокированы потоки, ожидающие сообщения на нее.

Ответ 3

@gstackoverflow: Основная проблема ограниченной очереди заключается в том, что она имеет максимальную емкость, поэтому, если ваша ограниченная очередь заполнена, вы будете заблокированы, когда захотите добавить эту "Ядовитую таблетку".

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

Изменить. Например, более тысячи предложений позволяют увидеть простой пример (все кредиты для примера переходят на Java Concurrency в Practice), с потоком производителя и потребительским потоком

public class CrawlerThread extends Thread { //The Producer Thread
  public void run() {
    try {
      crawl(root);
    } catch (InterruptedException e) { /* fall through */ }
    finally {
      while (true) {
        try {
          queue.put(POISON);
          break;
        } catch (InterruptedException e1) { /* retry */ }
      }
    }
  }
  private void crawl(File root) throws InterruptedException {
    //some code
  }
}
public class IndexerThread extends Thread { //The consumer Thread
  public void run() {
    try {
      while (true) {
        File file = queue.take();
        if (file == POISON)
        break;
        else
        indexFile(file);
      }
    } catch (InterruptedException consumed) { }
  }
}

Теперь, когда вы просматриваете Thread Producer (CrawlerThread), вы видите, что пилюля Яда размещается либо в конце прогона, либо в более тяжелой ситуации, когда происходит исключение.

Теперь позвольте сказать, что вы хотите использовать ограниченную очередь в качестве интерфейса между производителем и потребителем, пусть предположим, что очередь заполнена в момент времени t, а исключение возникает у производителя в момент времени t, производитель не будет в состоянии разместить пилюлю Яда в очереди, и вместо того, чтобы отключить потоки потребителей, потребитель все равно будет ждать появления элементов в очереди. Таким образом, почему подход "Ядовитая таблетка" не рекомендуется, если вы используете ограниченную очередь, потому что это потенциально может привести к неожиданному результату.

Ответ 4

Я думаю, что автор Java Concurrency In Practice может сказать это:

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

Можно добавить логику. Например, мы можем принудительно применять отравленные таблетки, которые всегда добавляются и никогда не удаляются. В этом случае может существовать ограниченная очередь.