2012-05-01 64 views
0

我正在爲我的操作系統課程做一個CPU調度模擬器項目。該程序應該由兩個線程組成:生產者線程和消費者線程。生產者線程包括在系統中生成進程的生成器以及選擇多個進程並將其放入稱爲緩衝區類型爲ReadyQueue的Object(由消費者和生產者共享的對象)的長期調度程序。消費者線程包括短期調度程序,它從隊列中獲取進程並啓動調度算法。我編寫了整個程序,沒有使用線程,但它的工作正常,但現在我需要添加線程,而且我從來沒有使用過線程,所以我很感謝有人能告訴我如何修改我在下面展示的代碼來實現所需的線程。生產者/消費者線程不給結果

這裏的生產者類實現:

public class Producer extends Thread{ 

    ReadyQueue Buffer = new ReadyQueue(20); // Shared Buffer of size 20 between consumer and producer 
    JobScheduler js = new JobScheduler(Buffer); 

    private boolean systemTerminate = false; // Flag to tell Thread that there are no more processes in the system 

    public Producer(ReadyQueue buffer) throws FileNotFoundException{ 
     Buffer = buffer; 
     Generator gen = new Generator(); // Generator generates processes and put them in a vector called memory  
     gen.writeOnFile(); 
    } 

    @Override 
    public void run() { 

     synchronized(this){ 
      js.select(); // Job Scheduler will select processes to be put in the Buffer 

      Buffer = (ReadyQueue) js.getSelectedProcesses(); 

      while(!Buffer.isEmpty()){  
       try { 
        wait();  // When Buffer is empty wait until getting notification 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       systemTerminate = js.select(); 
       Buffer = (ReadyQueue) js.getSelectedProcesses(); 
       if(systemTerminate)  // If the flag's value is true the thread yields 
        yield(); 
      } 
     } 
    } 

    public ReadyQueue getReadyQueue(){ 
     return Buffer; 
    } 
} 

這是消費類的實現:

public class Consumer extends Thread{ 

    ReadyQueue Buffer = new ReadyQueue(20); 
    Vector<Process> FinishQueue = new Vector<Process>(); 
    MLQF Scheduler ; 
    public Consumer(ReadyQueue buffer){ 
     Buffer = buffer; 
     Scheduler = new MLQF(Buffer,FinishQueue); // An instance of the multi-level Queue Scheduler 
    } 

    @Override 
    public void run() { 
     int count = 0;   // A counter to track the number of processes 

     while(true){ 
      synchronized(this){ 
       Scheduler.fillQueue(Buffer); // Take contents in Buffer and put them in a separate queue in the scheduler 
         Scheduler.start();    // Start Scheduling algorithm 
       count++; 
      } 
      if(count >= 200) // If counter exceeds the maximum number of processes thread must yeild 
       yield(); 
      notify();    // Notify Producer thread when buffer is empty 
     } 
    } 

    public void setReadyQueue(ReadyQueue q){ 
     Buffer = q; 
    } 
} 

這是主要的主題:

public class test { 

    public static void main(String[] args) throws FileNotFoundException,InterruptedException {  
     ReadyQueue BoundedBuffer = new ReadyQueue(20); 
     Producer p = new Producer(BoundedBuffer); 
     Consumer c = new Consumer(p.getReadyQueue()); 
     p.start(); 
     System.out.println("Ready Queue: "+p.getReadyQueue()); 
     p.join(); 
     c.start(); 
     c.join(); 
     } 
} 

預先感謝您。

回答

1

您的代碼存在的一個問題是它在多線程生產者/消費者模型中遇到了一個常見的錯誤。您必須使用while環視wait()調用。例如:

try { 
    // we must do this test in a while loop because of consumer race conditions 
    while(!Buffer.isEmpty()) { 
     wait();  // When Buffer is empty wait until getting notification 
     ... 
    } 
} catch (InterruptedException e) { 
    e.printStackTrace(); 
} 

的問題是,如果您有消費,你可能notify線程多線程但隨後另一個線程發過來的,通過和出隊剛剛添加的項目。當線程在收到通知後從WAIT隊列移動到RUN隊列時,通常會放在隊列的末尾,可能位於等待在this上同步的其他線程之後。

有關詳情,請參閱我的documentation about this

+0

謝謝你的回覆灰色。你能否更具體地說明哪個線程導致了這個錯誤?消費者還是生產者?或者,也許告訴我如何解決這個問題,因爲我是線程新手。 – Samantha

+0

另外'notify'方法需要在'synchronized'塊中。 – Gray

+0

該錯誤發生在'while(true)'loop @Samantha消費者。我在答覆中提供的鏈接具有所有細節。每當你像消費者一樣等待時,你必須再次測試你正在等待的狀態。 – Gray