2015-04-05 89 views
1

我比較新線程在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) 
{ 
} 

而且我得到以下輸出:基於Java中的線程我目前的理解

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 

如果(指數%10 == 0 & &索引== 10)塊將通知其它的線程來運行,並等待其它完成並同樣適用於第二個。現在它不是第一次工作。但是當索引== 20時,thread2停止工作並且thread1繼續打印30。

感謝您的幫助。 :)

+2

'等待()'和'通知()'是低級同步原語。如果你想等待另一個線程的動作,那麼通常你需要'java.util.concurrent.Semaphore'或'java.util.concurrent.CountDownLatch' – NamshubWriter 2015-04-05 05:34:38

回答

-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 – 2015-04-05 16:10:25

2

最根本的問題是,你們已經有了其中兩個線程進入的同時循環的競爭條件。

你需要安排它,使得只有一個被允許進入,另一個必須立即等待。

你可以嘗試像下面這樣的循環,它是互斥的。一個線程將被允許進入並開始遞增,另一個線程必須停止,直到第一個線程調用obj.wait()

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

我一直在使用共享反對類寫道一個簡單的代碼命名的計數器,它會跟蹤計數器細節,寫了兩個線程ThreadOne和ThreadTwo和主要應用類,如下給出。

正如其他人所建議的那樣,您可以使用像Semaphore或Lock類這樣的高級鎖對象。

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(缺省CLI)@ 多線程---

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