2015-04-05 2 views
1

Я относительно новый Threading в java, и я пытался выполнить следующую работу. Будут запущены две нитки. Thread1 будет печатать от 1 до 10, а затем ждать, пока Thread2 завершит печать 11-20, а затем завершит свою задачу и сообщит thread1 для печати 21-30, а затем прекратит работу thread1. Это код, который я использовал:Ждите, пока один нить закончится в java

private Thread thread = null; 
private String name = null; 
private static Object obj = new Object(); 
private static int index = 1; 

public childThread(Thread t, String name) 
{ 
    this.name = name; 
    this.thread = t; 
} 
public void run() 
{  
try 
{ 
    while (true) { 
    Thread.sleep(500); 
    if (index % 10 == 0 && index == 10) { 
     System.out.println("Waiting for Thread2"); 
     synchronized (obj) { 
     obj.notify(); 
     obj.wait(); 
     } 
    } 
    else if (index % 10 == 0 && index == 20) { 
     System.out.println("Waiting for Thread1"); 
     synchronized (obj) { 
     obj.notify(); 
     obj.wait(); 
     } 
    } 
    else if(index == 30) 
    { 
     obj.wait(); 
    } 


    synchronized (obj) { 
     System.out.println(name + " ><>< " + index); 
     index++; 
    } 
    } 
} 
catch(Exception e) 
{ 
} 

И я получаю следующий результат:

Thread2 ><>< 1 
Thread1 ><>< 2 
Thread2 ><>< 3 
Thread1 ><>< 4 
Thread2 ><>< 5 
Thread1 ><>< 6 
Thread1 ><>< 7 
Thread2 ><>< 8 
Thread2 ><>< 9 
Thread1 ><>< 10 
Thread2 ><>< 11 
Thread1 ><>< 12 
Thread2 ><>< 13 
Thread1 ><>< 14 
Thread2 ><>< 15 
Thread1 ><>< 16 
Thread2 ><>< 17 
Thread1 ><>< 18 
Thread2 ><>< 19 
Waiting for Thread1 
Waiting for Thread1 
Thread1 ><>< 20 
Thread1 ><>< 21 
Thread1 ><>< 22 
Thread1 ><>< 23 
Thread1 ><>< 24 
Thread1 ><>< 25 
Thread1 ><>< 26 
Thread1 ><>< 27 
Thread1 ><>< 28 
Thread1 ><>< 29 

на основе моего понимания в Java многопоточности.

, если (индекс 10% == 0 & & индекс == 10) блок будет уведомлять другую нить для запуска и ждать, пока другая завершена и же самое для второго. Теперь это не работает в первый раз. Но когда index == 20, thread2 перестает работать, а thread1 продолжает печатать30.

Благодарим за помощь. :)

+2

'ожидания() и' Notify() 'являются низкими примитивы синхронизации уровня. Если вы хотите подождать действия другого потока, тогда обычно вы хотите либо 'java.util.concurrent.Semaphore', либо' java.util.concurrent.CountDownLatch' – NamshubWriter

ответ

-2

Это рабочий код, надеюсь, что это помогает

public static void main(String[] args) { 
    final Object lock = new Object(); 
    final Thread t2 = new Thread() { 
     public void run() { 
      synchronized (lock) { 
       try { 
        lock.wait(); 
       } catch (InterruptedException e) { 
        throw new RuntimeException(e); 
       } 
      } 
      for(int i = 11; i < 21; i++) System.out.println(i); 
     } 
    }; 
    Thread t1 = new Thread() { 
     public void run() { 
      for(int i = 1; i < 11; i++) System.out.println(i); 
      synchronized (lock) { 
       lock.notifyAll(); 
      } 
      try { 
       t2.join(); 
      } catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
      for(int i = 21; i < 31; i++) System.out.println(i); 
     } 
    }; 
    t1.start(); 
    t2.start(); 
} 
+0

. Ваш ответ может работать большую часть времени, но он содержит фатальный изъян: Как сказал @NamshubWriter, 'wait()' и 'notify()' являются _primitives_. Они предназначены для использования очень определенным образом. http://stackoverflow.com/questions/27554127/avoid-waiting-for-a-terminated-thread/27556424#27556424 –

2

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

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

Возможно, вы можете попробовать цикл, подобный следующему, который является взаимоисключающим. Одному потоку будет разрешено вводить и начинать приращение, а другое - останавливаться до тех пор, пока первый поток не вызовет obj.wait().

synchronized(obj) { 
    while (index < 30) { 
     Thread.sleep(500); 
     if (index > 0 && index % 10 == 0) { 
      obj.notify(); 
      obj.wait(); 
     } 
     index++; 
    } 
} 
0

Я написал один простой код, используя Shared возражала класс по имени счетчика, который будет отслеживать детали счетчика и написал две нити ThreadOne и ThreadTwo и основной класс приложения, как указано ниже.

Как и другие, вы можете использовать объект блокировки высокого уровня, например, класс Семафор или замок.

package thread.communication.demo; 

public class Counter { 

private int count = 1; 

private boolean lockTrue = false; 

public synchronized void incrFirstThread() { 

    while (lockTrue) { 

     try { 
      wait(); 

     } catch (InterruptedException ex) { 
      Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    lockTrue = true; 

    for (int i = count; i < count + 10; i++) { 
     System.out.println(i + Thread.currentThread().getName()); 
    } 

    count += 10; 

    notifyAll(); 

} 

public synchronized void incrSecondThread() { 

    while (!lockTrue) { 

     try { 
      wait(); 

     } catch (InterruptedException ex) { 
      Logger.getLogger(Counter.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    lockTrue = false; 

    for (int i = count; i < count + 10; i++) { 
     System.out.println(i + Thread.currentThread().getName()); 
    } 

    count += 10; 

    notifyAll(); 
} 
} 



package thread.communication.demo; 

public class ThreadOne extends Thread{ 

Counter counter; 

ThreadOne(Counter counter) 
{ 
    this.counter=counter; 
} 

@Override 
public void run() { 

    while (true) { 

     counter.incrFirstThread(); 
    } 
} 
} 

package thread.communication.demo; 

public class ThreadTwo extends Thread { 

Counter counter; 

ThreadTwo(Counter counter) 
{ 
    this.counter=counter; 
} 

@Override 
public void run() { 

    while (true) { 

     counter.incrSecondThread(); 
    } 
} 
} 

package thread.communication.demo; 

public class ThreadMain { 

public static void main(String[] args) { 

    Counter counter=new Counter(); 

    ThreadOne one = new ThreadOne(counter); 

    ThreadTwo two = new ThreadTwo(counter); 

    one.start(); 

    two.start(); 
} 
} 

Выход такой, как указано ниже.

[INFO] [INFO] --- exec-maven-plugin: 1.2.1: EXEC (по умолчанию-кли) @ Многопоточность ---

1Thread-0 2Thread-0 3Thread-0 4Thread-0 5Thread-0 6Thread-0 7Thread-0 8Thread-0 9Thread-0 10Thread-0 11Thread -1 12Thread-1 13Thread-1 14Thread-1 15Thread-1 16Thread-1 17Thread-1 18Thread-1 19Thread-1 20Thread-1 21Thread-0 22Thread-0 23Thread-0 24Thread-0 25Thread-0 26Thread-0 27Thread-0 28Thread-0 29Thread-0 30Thread-0 31Thread-1 32Thread-1 33Thread-1 34Thread-1 35Thread-1 36Thread-1 37Thread-1 38Thread-1 39Thread-1 40Thread-1 41Thread-0 42Thread-0 43Thread-0 44Thread-0 45Thread-0 46Thread-0 47Thread-0 48Thread-0 49Thread-0 50Thread-0 51Threa d-1 52Thread-1 53Thread-1 54Thread-1 55Thread-1 56Thread-1 57Thread-1 58Thread-1 59Thread-1 60Thread-1

Смежные вопросы