2016-01-30 4 views
1

У меня проблема с отладкой моего SynchronousQueue. его в студии Android, но не имеет значения для его кода Java. Я передаю истину конструктору SynchronousQueue, поэтому его «справедливое» означает его очередь fifo. Но он не подчиняется правилам, его все еще разрешает потребителю печатать сначала и продюсеру после. Вторая проблема, которую я имею, - это то, что я хочу, чтобы эти потоки никогда не умирали, думаете ли вы, что я должен использовать цикл while для производителя и потребительского потока и позволить им «производить и потреблять» друг друга?Решение проблемы параллелизма между производителями и поставщиками SynchronousQueue. Свойство Fairness не работает

вот мой простой код:

package com.example.android.floatingactionbuttonbasic; 


import java.util.concurrent.SynchronousQueue; 

import trikita.log.Log; 


public class SynchronousQueueDemo { 


    public SynchronousQueueDemo() { 
    } 


    public void startDemo() { 
     final SynchronousQueue<String> queue = new SynchronousQueue<String>(true); 

     Thread producer = new Thread("PRODUCER") { 
      public void run() { 
       String event = "FOUR"; 
       try { 
        queue.put(event); // thread will block here 
        Log.v("myapp","published event:", Thread 
          .currentThread().getName(), event); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 
     }; 

     producer.start(); // starting publisher thread 

     Thread consumer = new Thread("CONSUMER") { 
      public void run() { 
       try { 
        String event = queue.take(); // thread will block here 
        Log.v("myapp","consumed event:", Thread 
          .currentThread().getName(), event); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

      } 
     }; 

     consumer.start(); // starting consumer thread 

    } 

} 

чтобы начать темы я простой вызов new SynchronousQueueDemo().startDemo();

Журналы всегда выглядят так, независимо от того, что я прохожу в SynchronousQueue конструктору быть «справедливым»:

/SynchronousQueueDemo$2$override(26747): myapp consumed event: CONSUMER FOUR 
V/SynchronousQueueDemo$1$override(26747): myapp published event:PRODUCER FOUR 

Проверка docs here, он говорит следующее:

public SynchronousQueue (boolean fair) Создает синхронный вызов с указанной политикой справедливости. Параметры: fair - если true, ожидающие потоки утверждают в заказе FIFO для доступа; иначе порядок не указан.

ответ

1
  1. политика Справедливость относится к порядку, в котором считывается очередь. Порядок исполнения для производителя/потребителя предназначен для того, чтобы потребитель взял(), выпустив производителя (который блокировал put()). Установите справедливость = true, если порядок потребления важен.

  2. Если вы хотите, чтобы потоки были живы, у вас есть условие цикла, которое хорошо срабатывает при прерывании (см. Ниже). Предположительно, вы хотите поместить Thread.sleep() в Producer, чтобы ограничить скорость, с которой производятся события.

    public void run() { 
        boolean interrupted = false; 
        while (!interrupted) { 
         try { 
          // or sleep, then queue.put(event) 
          queue.take(event); 
         } catch (InterruptedException e) { 
          interrupted = true;; 
         } 
        } 
    } 
    
+0

прерван всегда будет ложными в этом случае – thedarkpassenger

+0

Что ты имеешь в виду? Политика остановки потока - прерывать(); который затем установит прерванный = истинный. Пожалуйста, объясните, и я исправлю. Спасибо. –

+0

Да, простите, я плохой плохой разговор. – thedarkpassenger

1

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

1) Теперь, если вы начнете делать queue.put() без каких-либо queue.take(), поток будет блокироваться там. Итак, как только у вас будет queue.take(), поток производителя будет разблокирован.

2) Аналогичным образом, если вы начинаете делать queue.take(), он будет блокироваться до тех пор, пока не появится производитель. Поэтому, если у вас есть queue.put(), потребительский поток будет заблокирован.

Как только будет выполнен queue.take(), потоки Продюсера и Потребителя будут разблокированы. Но вы понимаете, что Producer и Consumer работают в отдельных потоках. Таким образом, любое из сообщений, которые вы ставите после блокирующих вызовов, может быть выполнено. В моем случае порядок вывода был таким. Продюсер печатался первым.

В/SynchronousQueueDemo $ 1 $ переопределение (26747): MyApp опубликовала событие: ПРОДЮСЕР ЧЕТВЕРТОГО /SynchronousQueueDemo $ 2 $ переопределения (26747): MyApp потребляется событие: ПОТРЕБИТЕЛЬСКИЙ ЧЕТВЕРТОГО

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

  • Нет связанных вопросов^_^