Лучшая практика для массивов потоков (Java) - PullRequest
1 голос
/ 02 декабря 2011

У меня есть некоторый опыт работы с потоками в Java, но мне интересно ...

Как лучше хранить несколько потоков, чтобы я мог обращаться к ним как по отдельности, так и в группе?

Мое собственное решение - создать класс threadArray, но, естественно, я бы предпочел нативный класс, который намного надежнее.

Заранее спасибо!


1012 * редактировать *

Видимо, функциональность имеет большое значение для лучшего метода. Хорошо, я приведу пример:

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

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

Это помогает?

Ответы [ 5 ]

3 голосов
/ 02 декабря 2011

Я бы использовал ExecutorService для управления своими потоками как пулом и поместил Future s, которые мне дают при добавлении моего Threads в пул в некоторой форме Collection.

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

Редактировать в ответ на ваш

Вы можете использовать shutdownNow метод ExecutorService для отмены всех запущенных потоков.

Пример (не решение вашей проблемы, но покрывает большинство преимуществ использования Исполнителей):

// Thread pool for the collectors.
ExecutorService threads = Executors.newFixedThreadPool(MAX_THREADS);
...
// Futures of all collectors running in the pool.
ConcurrentLinkedQueue<Future> collectors = new ConcurrentLinkedQueue<Future>();
...
// Make my Callable.
Callable<Void> c = new FileListCollector(path, recurse, filter);
// Start it up and keep track of it so we can find out when it has finished.
collectors.add(threads.submit(c));
...

// Called when nothing in queue.
private void checkForFinished() {
  // Count the running threads.
  int runningThreads = 0;
  try {
    // Track dead ones to remove.
    List<Future> deadThreads = new LinkedList<Future>();
    // Walk all collectors.
    for (Future f : collectors) {
      // I've seen f being null once. No idea how.
      if (f != null) {
        // If it's not done then it's running.
        if (!f.isDone()) {
          // Count it.
          runningThreads += 1;
        } else {
          // Mark for deletion.
          deadThreads.add(f);
        }
      }
    }
    // Clear dead threads - just to be tidy.
    collectors.removeAll(deadThreads);
  } catch (ConcurrentModificationException cme) {
    // Probably a new thread has been started while I was checking!
    // Therefore almost certainly NOT all finished.
    runningThreads += 1;
  }
  // If no threads are left, we're done.
  if (runningThreads == 0) {
    // Finished! Close everything down.
    close();
  }
}

// Close down the whole system.
public void close() {
  // Use the fileQueue state to indicate closed.
  if (!fileQueue.isClosed()) {
    // Close the queue ... unblocking all collectors (I hope).
    fileQueue.close();
    // Shut them down agressively as this may be called by user prematurely as well as by me.
    threads.shutdownNow();
    // Wait until all is done.
    boolean terminated = false;
    do {
      try {
        // Wait up to 1 second for termination.
        terminated = threads.awaitTermination(1, TimeUnit.SECONDS);
      } catch (InterruptedException ex) {
        // Ignore the interrupt! If I exit here we will probably leak.
      }
    } while (!terminated);
    log("! All done");
  }
}
1 голос
/ 02 декабря 2011

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

0 голосов
/ 02 декабря 2011

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

«Нативный» класс не обязательно обеспечит вам большую надежность, если вы используете несколько баз для записи на базе.

Я не уверен, сколько лет этот след , но охватывает основы синхронизации, многопоточный доступ и некоторые другие вещи.

0 голосов
/ 02 декабря 2011

Почему бы не использовать одну из Java Collection Framework?

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

Просто выберите коллекцию, которая лучше всего соответствует вашим потребностям.

Наряду с этим вы можете использовать методы в классе Collections для созданиясинхронизированные версии Коллекций по мере необходимости.

0 голосов
/ 02 декабря 2011

Я часто просто помещаю Thread ссылки в стандартные контейнеры.

Выбор контейнера зависит от того, что именно вы хотите сделать с объектами.

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