как сделать вектор синхронизированным так, чтобы из двух потоков к нему мог обращаться только один поток - PullRequest
1 голос
/ 21 сентября 2011

В моей программе есть два класса A и B, оба расширяют Thread, теперь B имеет очередь с именем CommandQueue. Теперь поток B получает к нему доступ, пока он не становится пустым, а поток класса A обращается к нему всякий раз, когда обнаруживаются новые команды для вставки в него. Как я могу сделать эту очередь синхронизированной так, чтобы одновременно оба потока не могли получить к ней доступ, а когда один использовал эту очередь, освободить ее для использования другим потоком. Также, пожалуйста, предложите, если не будет никаких проблем, если я не синхронизирую их.

Ответы [ 5 ]

3 голосов
/ 21 сентября 2011

Кажется, вам нужно BlockingQueue вместо простого вектора.

BlockingQueue.put (E e): вставляет указанный элемент в эту очередь, ожидая, если необходимо, места для доступа.

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

2 голосов
/ 21 сентября 2011

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

1 голос
/ 21 сентября 2011

Всякий раз, когда вы хотите использовать потоки и очереди вместе для выполнения работы, очень вероятно, что ExecutorService - лучший выбор. Это потому, что они предназначены для обобщения обеих этих концепций.

ExecutorService es = Executors.new (pick a thread pool of your choice)

// in thread A
es.execute(new Runnable() {
   public void run() {
      // task to run on Thread B
   }
});

// in thread A
Future<Type> future = es.submit(new Callable<Type>() {
   public Type call() {
      // task to run on Thread B and ...
      return type;
   }
});

// later get the result
Type t = future.get();

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

0 голосов
/ 21 сентября 2011

Просто синхронизируйте потоки, добавив «синхронизированный».

public void synchronized Producer(Object whatever) {
    // Insert into the Queue here
     Queue.add(whatever);
}

public Object synchronized Consumer() {
    // Get Values out of the Queue here
    Queue.remove(whatever);
}

Просто вызовите функции там, где вам это нужно, и все будет работать нормально и "полностью синхронизировано":)

0 голосов
/ 21 сентября 2011

Вы можете использовать: ConcurrentLinkedQueue или другую коллекцию с ожиданием / уведомлением.

I.ConcurrentLinkedQueue

  ConcurrentLinkedQueue<Object> myQueue = new ConcurrentLinkedQueue<Object>();

  ...
  // first thread
  myQueue.add(someObject);

  ...
  // seconds thread
  Object someObject = myQueue.poll()

II.Подождите / Уведомить

Код только для примера.Вам нужно будет обработать исключение и прочитать о проблеме пробуждения потока.

  ArrayList<Object> objects = new ArrayList<Object>();

  ...    
  // first thread
  synchronized(objects) {
      objects.add(someObject);
      objects.notifyAll();
  }

  ...
  // second thread
  synchronized(objects) {
      objects.wait();
      for (Object someObject: objects) {
          // do something with someObject
      }
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...