2016-09-15 94 views
-2

我正在嘗試編寫一個程序,其中兩個線程同時運行。一個是打印傑克,另一個是瓊斯。預期產量爲: 傑克瓊斯傑克瓊斯等。但我在呼叫notifyAll()時遇到問題。誰能告訴我有什麼問題?按順序在兩個線程中打印兩個不同的字符串

異常

Starting thread 
Jack Jones Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.IllegalMonitorStateException 
at java.lang.Object.notifyAll(Native Method) 
at JonesThread.printJones(JonesThread.java:32) 
at JonesThread.run(JonesThread.java:14) 
java.lang.IllegalMonitorStateException 
at java.lang.Object.notifyAll(Native Method) 
at JackThread.printJack(JackThread.java:36) 
at JackThread.run(JackThread.java:15) 

傑克主題

import java.util.concurrent.atomic.AtomicBoolean; 

public class JackThread extends Thread { 

AtomicBoolean i; 

public JackThread(AtomicBoolean i2) { 

    this.i = i2; 
} 

public void run() { 
    while (true) { 
     try { 
      printJack(); 
      Thread.sleep(10000); 

     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

private void printJack() throws InterruptedException { 

    synchronized (i) { 
     while (i.get()) { 
      { 
       wait(); 
      } 
     } 

     System.out.print("Jack "); 
     i.set(true); 
     notifyAll(); 

    } 
} 
} 

瓊斯主題

import java.util.concurrent.atomic.AtomicBoolean; 

public class JonesThread extends Thread { 

AtomicBoolean i; 

public JonesThread(AtomicBoolean i2) { 
    this.i = i2; 
} 

public void run() { 
    while (true) { 
     try { 
      printJones(); 

      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

private void printJones() throws InterruptedException { 
    synchronized (i) { 
     while (!i.get()) { 
      wait(); 
     } 

     System.out.print("Jones "); 
     i.set(false); 
     notifyAll(); 
    } 
} 
} 

MainProgram(主程序)

import java.util.concurrent.atomic.AtomicBoolean; 

public class ThreadMain { 
public static void main(String args[]) { 
    AtomicBoolean i = new AtomicBoolean(false); 
    System.out.println("Starting thread"); 
    JackThread t1 = new JackThread(i); // Will give chance to Print Jack first 
    JonesThread t2 = new JonesThread(i);// Jones will follow Jack 

    t1.start(); 
    t2.start(); 
} 
} 

回答

2

wait定義是,如果你說

someObject.wait(); 

線程會等待,直到有人通知someObject的顯示器。另一個線程可以通過調用

someObject.notify(); // or notifyAll 

但事情是,線程必須通過使用相同的對象進行協調。您還沒有指定的對象,所以你wait()相當於

this.wait(); 

也就是說,JackThread對象等着有人通知自己。但沒有人通知JackThread對象。當您的通話JonesThreadnotifyAll(),這是一樣的

this.notifyAll(); 

,所以它本身通知,即一個JonesThread對象。所以基本上,你的兩個主題是在對自己說話,而不是對方說話。

看起來你已經設置了i爲已知兩個線程對象,所以你可以使用你的waitnotify,即i.wait()i.notifyAll()聲明:我沒有測試過它。

+0

謝謝,我試過並測試過,它工作。 – Incredible

相關問題