Можно ли использовать подход отравленной таблетки с ограниченными очередями? - PullRequest
17 голосов
/ 29 декабря 2011

В книге «Практика параллелизма на Java» (стр.156) есть утверждение, касающееся подхода ядовитая таблетка :

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

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

Ответы [ 4 ]

7 голосов
/ 29 декабря 2011

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

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

6 голосов
/ 30 декабря 2011

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

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

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

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 и сохранить их.

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

1 голос
/ 25 февраля 2017

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

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

Редактировать : В качестве примера говорится более тысячи предложений, давайте рассмотрим простой пример (все кредиты для примера идут на Java Concurrency на практике ) с потоком продюсера и потребительская нить:

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) { }
  }
}

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

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

0 голосов
/ 01 марта 2017

Я думаю, что автор (ы) параллелизма Java на практике может попытаться сказать следующее:

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

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

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