2017-04-16 57 views
1

通知想象,一個法師被要求5個指南,以幫助5個孩子打印的線路有n個文件。學校裏只有一臺打印機。現在,100多行的孩子應該等待其他孩子完成打印。我寫了下面的代碼如何使一個線程等待,並在Java

public enum Printer { 

printer; 

public synchronized void print(Kid kid) { 
    if(kid.getPagesToPrint()<100){ 
     System.out.println(kid.getName()+" is printing "+kid.getPagesToPrint()+" pages"); 
     notify(); 
    }else{ 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

}

的孩子類

public class Kid { 

private String name; 

private int pagesToPrint; 

public Kid(String name, int pagesToPrint) { 
    super(); 
    this.name = name; 
    this.pagesToPrint = pagesToPrint; 
} 

public int getPagesToPrint() { 
    return pagesToPrint; 
} 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

public void setPagesToPrint(int pagesToPrint) { 
    this.pagesToPrint = pagesToPrint; 
} 

}

的GuideThread類

public class GuideThread implements Runnable { 

private Kid kid; 

public GuideThread(Kid kid) { 
    super(); 
    this.kid = kid; 
} 

@Override 
public void run() { 
    Printer.printer.print(kid); 
} 

}

最後的大師班 公共類碩士{

public static void main(String[] args) { 
    for(int i=1;i<6;i++){ 
     Thread t = new Thread(new GuideThread(new Kid("Kid_"+i,i*23))); 
     t.start(); 
    } 
} 

}

當我執行它,該程序正在等待幾分鐘,然後terminates.Can有人糾正這個代碼,以便通知所有正在等待 的線程,然後再打印所有少於第一個頁面的頁面。

+0

的輸出如下Kid_3是印刷 69頁Kid_2是印刷 46頁Kid_1是印刷 23頁Kid_4正在打印92頁 –

+1

你的等待條件是錯誤的:有100多頁的孩子只能等待,如果另一孩子少於100歲。否則,孩子將永遠等待。同樣,等待(應該總是在循環內部)在你的代碼中,如果一個孩子等待並被通知,它不會結束打印:print()方法在等待wait()和notify()之後返回是你應該在這裏使用PriorityBlockingQueue首先打印小文檔,最後一個打印小文檔 –

+0

這是可能的,只有通過使用PriorityBlockingQueue ..我們不可以使用wait/notify/notifyAll方法嗎? –

回答

1

這裏:

for(int i=1;i<6;i++){ 
    Thread t = new Thread(new GuideThread(new Kid("Kid_"+i,i*23))); 
    t.start(); 
} 

最後一個線程來運行是100多頁打印的主題。
正如每個線程的處理是很短,每次運行線程的一個線程開始執行之前很有可能完成它的執行。

如果希望具有最大的頁面孩子要打印在第一線程中運行,使其開始爲第一個。

你的第二個問題是在這裏:

public synchronized void print(Kid kid) { 
    if(kid.getPagesToPrint()<100){ 
     System.out.println(kid.getName()+" is printing "+kid.getPagesToPrint()+" pages"); 
     notify(); 
    }else{ 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 
} 

if (kid.getPagesToPrint()>=100),孩子必須等待。
但是,如果沒有孩子通知他,因爲所有的孩子都已經完成了他們的印刷,最後一個孩子被卡住了。

所以,if(kid.getPagesToPrint()<100)顯然不足以決定那種是否可以打印。
你應該考慮在這種情況下等待孩子的存在。

它看起來像一門功課。我認爲這足以引導你。

+0

你應該考慮在這種情況下等待孩子的存在 - 你能解釋更多嗎? –

0

可能有點不同的方法將使用一個PriorityBlockingQueuehttps://docs.oracle.com/javase/7/docs/api/java/util/concurrent/PriorityBlockingQueue.html

你可以做的是:

  1. Comparator其使用的頁數打印比較Kids創建PriorityBlockingQueue
  2. 執行Printer類輪詢PriorityBlockingQueue新項目。
  3. 實施GuideThreadPriorityBlockingQueueKids並啓動Printer
  4. 這種方法還允許Kids將進行比較,並且基於要打印的頁面的數量在隊列中的其他Kids優先的連續進料。
  5. 它還允許清楚地分開程序的三個方面:生產,消費,優先化,允許它們分開進化。

希望這會有所幫助。