2013-05-12 2 views
4

У нас есть два потока J1 и J2. Как мы можем убедиться, что поток J2 запускается только после завершения выполнения J1 без использования метода join().Без использования Thread.Join(), как я могу получить такую ​​же функциональность

+6

почему вы не хотите использовать '.join'? – Alnitak

+0

Посмотрите на ['java.util.concurrent.Exchanger'] (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Exchanger.html). –

+1

Вы можете использовать синхронизатор 'java.util.concurrent': CountDownLatch, Семафор, Lock, это зависит от вашего usecase. – dcernahoschi

ответ

1

Я думаю, что это очень близко к тому, что делает Thread.join

public class Test1 { 

    public static void main(String[] args) throws Exception { 
     Thread t = new Thread(); 
     synchronized (t) { 
      t.start(); 
      while (t.isAlive()) { 
       t.wait(); 
      } 
     } 
    } 
} 

внимание магия - что-то просыпается t.wait() - это потому, что JVM уведомляет объект Thread, когда он завершает

+0

Мне очень нравится это решение. Однако я предпочел бы использовать метод «Lock» и «Condition». –

+0

Если вам понравилось первое решение, то см. Второе, это действительно то, как работают соединения –

+2

Ха-ха, +1. Если вы не можете использовать метод Thread.join, скопируйте его в свой собственный метод. –

4

Простой, используйте CountDownLatch.

Инициализировать CountDownLatch до 1 в main(). Передайте его как J1, так и J2. J2 просто ждет, когда защелка станет 0, используя await(). J2 устанавливает его в 0, как только это делается, используя countDown(), сигнализируя, что J1 запускается.

+1

Это решение имеет то преимущество, что даже если вы не можете использовать '.join()' (когда другой поток больше работы, которую нужно выполнить после синхронизации обоих потоков и, следовательно, не будет завершено). Вы можете использовать его вместо «.join()» и где '.join()' не является опцией. – dimo414

+0

+1 предпочтительный подход с использованием нового API параллелизма – ajduke

0

Другой способ для достижения этой цели является использование Locks

class X { 
     private final ReentrantLock lock = new ReentrantLock(); 
      // ... 

     public void m() { 
      lock.lock(); // block until condition holds 
      try { 
       // ... method body 
      } finally { 
       lock.unlock() 
      } 
     } 
    } 
Смежные вопросы