Как я получаю java.concurrency. CyclicBarrier для работы как ожидалось

Я - написание кода, которое будет метать икру два, распараллеливают и затем ожидают их для синхронизации использования класса CyclicBarrier. Проблема состоит в том, что циклический барьер не работает как ожидалось, и основной поток не ожидает отдельных потоков для окончания. Вот то, как мой код смотрит:

 class mythread extends Thread{
   CyclicBarrier barrier;
   public mythread(CyclicBarrier barrier) { 
       this.barrier = barrier;
      }

   public void run(){
            barrier.await();
       } 
 }



class MainClass{
 public void spawnAndWait(){
    CyclicBarrier barrier = new CyclicBarrier(2);
    mythread thread1 = new mythread(barrier).start();
    mythread thread2 = new mythread(barrier).start();
    System.out.println("Should wait till both threads finish executing before printing this");
  }
}

Какая-либо идея, что я делаю неправильно? Или есть ли лучший способ записать эти методы синхронизации барьера? Помогите.

7
задан spender 26 March 2010 в 09:40
поделиться

3 ответа

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

CyclicBarrier barrier = new CyclicBarrier(3);
mythread thread1 = new mythread(barrier).start();
mythread thread2 = new mythread(barrier).start();
barrier.await(); // now you wait for two new threads to reach the barrier.
System.out.println("Should wait till both threads finish executing before printing this");

Кстати. Не расширяйте класс Thread без необходимости. Реализуйте Runnable и передайте реализации объектам Thread. Как это:

class MyRunnable implements Runnable {
    public void run(){
        // code to be done in thread
    }
}

Thread thread1 = new Thread(MyRunnable);
thread1.start();

РЕДАКТИРОВАТЬ
Обоснование отказа от расширения Thread.
Практическое правило - как можно меньше взаимодействовать. Наследование - это очень прочная связь между классами. Вы должны унаследовать от Thread, если хотите изменить некоторые из его поведения по умолчанию (т.е. переопределить некоторые методы) или хотите получить доступ к некоторым защищенным полям класса Thread.Если вам это не нужно, вы выбираете более слабую связь - реализуете Runnable и передаете его в качестве параметра конструктора экземпляру Thread.

14
ответ дан 6 December 2019 в 09:59
поделиться

Передайте экземпляр Runnable конструктору вашего CyclicBarrier следующим образом.

CyclicBarrier barrier = new CyclicBarrier(2, new Runnable() {

    @Override
    public void run() {
        System.out.println("Should wait till both threads finish executing before printing this");
    }
});

new mythread(barrier).start();
new mythread(barrier).start();
2
ответ дан 6 December 2019 в 09:59
поделиться

Вы ищете Thread.join () метод ...

thread1.join();
thread2.join();
System.out.println("Finished");

РЕДАКТИРОВАТЬ: из-за комментариев ...

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

2
ответ дан 6 December 2019 в 09:59
поделиться