Использование более одного потока в Java - PullRequest
3 голосов
/ 25 ноября 2011

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

private static class workerThread extends Thread {

        workerThread(){
            super();
        }


        public void run(){
             while (!workQueue.isEmpty()) {

            String x = workQueue.remove();
            //System.out.println("work queue size: " + workQueue.size());
            Vector<String> list2 = new Vector<String>((Vector) table.get(x));
            list2 = process(x, list2);
            //System.out.println(list2 + "list2");
            table.put(x, list2);

            //System.out.println(x + "key" + "value" + vvv);

        }

        }

Это класс рабочего потока потока, я пытался вызвать его, просто создав два новых потока:

workerThread wt = new workerThread();
    workerThread wt2 = new workerThread();
    wt.start();
    wt2.start();
    try {
        wt.join();
        wt2.join();
    } catch (InterruptedException ex) {
        Logger.getLogger(includeCrawler.class.getName()).log(Level.SEVERE, null, ex);
    }

Я не уверен, правильно ли это, или будет какая-то польза от ожидания присоединений? Спасибо за любую помощь.

Ответы [ 3 ]

2 голосов
/ 25 ноября 2011

Более чистый и масштабируемый способ сделать это - использовать пул потоков, созданный классом Executors .

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

1 голос
/ 25 ноября 2011

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

ExecutorService executor = Executors.newSingleThreadExecutor();
Future<MyObject> f =
    executor.submit(new Callable<MyObject>() {

      @Override
      public MyObject call() throws Exception {
        MyObject obj = new MyObject();
        // do stuff
        return obj;
      }

    });

MyObject myObject =
    new MyObject();

try {
  myObject = f.get(500, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e) {
  // stuff
}
catch (ExecutionException e) {
  // stuff
}
catch (TimeoutException e) {
  // stuff
}
finally {
  executor.shutdown();
}

В этом случае я хотел подождать не более 500 мсек до истечения времени ожидания, но это необязательно. Надеюсь, это поможет.

1 голос
/ 25 ноября 2011

Всего несколько ссылок, я думаю, вы хотите использовать BlockingQueue вместе с ExecutorService и Runnable или Callable.

final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); возможно даже переменную экземпляра (privatestatic final ExecutorService POOL = ...).Для приложений, связанных с вводом / выводом, вы можете использовать больше потоков, чем доступных процессоров.Опять же, вы не хотите использовать Vector.Используйте другую реализацию List (обычно используется ArrayList).

Кстати: если вы хотите освоить параллельное программирование, вы также можете прочитать об Akka и Actors / STM вместо использования обычноймодель общей изменчивости.

Редактировать: Я бы определенно рекомендовал http://pragprog.com/book/vspcon/programming-concurrency-on-the-jvm и эффективную Java от Джоша (БА).

...