2017-04-11 76 views
0

我寫了一些代碼使用同步類,它的工作原理,但不是我想如何。我需要它僅在緩衝區爲空時將糖果放入有界緩衝區數組中,然後放置線程不會重新填充,直到緩衝區再次爲空。我嘗試了幾個不同的東西,但似乎沒有任何工作。Java線程程序

import java.util.Scanner; 

class CandyBowl 
{ 
    private int[] buf; 
    private int in = 0; 
    private int out= 0; 
    private int count = 0; 
    private int size; 

CandyBowl(int size) 
{ 
    this.size = size; 
    buf = new int[size]; 
} 

synchronized public void put(int o) 
{ 
    while (count==size) 
    { 
     System.out.println("Candy bowl is full!"); 
     try 
     { 
      wait(); 
     } 
     catch(InterruptedException e){} 
    } 
     //System.out.println("put"); 
     buf[in] = o; 
     ++count; 
     in=(in+1) % size; 
     notifyAll(); 
} 

synchronized public int get() 
{ 
    while (count==0) 
    { 
     System.out.println("Candy bowl is empty! Get the TA!"); 
     try 
     { 
      wait(); 
     } 
     catch(InterruptedException e){} 
    } 
    //System.out.println("get"); 
    int ret_val = buf[out]; 
    --count; 
    out=(out+1) % size; 
    notifyAll(); 
    return (ret_val); 
} 
} 

class PieceOfCandy 
{ 
    private int candy = 0; 

    public synchronized int getNextPiece() 
    { 


return ++candy; 
    } 
} 

class Producer extends Thread 
{ 

    CandyBowl buf_; 
    PieceOfCandy piece; 

    Producer(CandyBowl b, PieceOfCandy kitkat) 
    { 
     buf_ = b; 
     piece = kitkat; 
    } 

    public void run() 
    { 
     try 
     { 
      while(true) 
      { 
       buf_.put(piece.getNextPiece()); 
       Thread.sleep(250); 
      } 
     } 
     catch (InterruptedException e) 
     { 
      System.out.println("TA: I need to buy more candy!"); 
     } 
    } 
} 

class Consumer extends Thread 
{ 
    CandyBowl buf_; 
    char ident; 

    Consumer(CandyBowl b, char id) 
    { 
     buf_ = b; 
     ident = id; 
    } 

    public void run() 
    { 
     try 
     { 
      int value; 
      while(true) 
      { 
       value = buf_.get(); 
       System.out.println("Professor " + ident + " took candy " + value); 
       Thread.sleep(1000); 
      } 
     } 
     catch (InterruptedException e) 
     { 
      System.out.println("Professors " + ident + ": I guess I'll teach now."); 
     } 
    } 
} 

public class OS_BoundedBuffer 
{ 
    public static void main (String args[]) 
    { 
     char id = 'A'; 
     PieceOfCandy candy = new PieceOfCandy(); 

     Scanner sc = new Scanner(System.in); 
     System.out.print("How many Professors want to think? "); 
     final int numProfs = sc.nextInt(); 

     CandyBowl bowl = new CandyBowl(10); 
     System.out.println(); 

     Producer teachAssist = new Producer(bowl, candy); 
     Consumer profs[] = new Consumer[numProfs]; 

     for (int i = 0; i < numProfs; i++) 
     { 
      profs[i] = new Consumer(bowl, id); 
      id = (char)(id + '\001'); 
     } 

     teachAssist.start(); 

     for (int i = 0; i < numProfs; i++) 
      profs[i].start(); 

     try 
     { 
      Thread.sleep(30000); 

      System.out.println("Main: I'm tired of waiting!"); 
      for(int i = 0; i < numProfs; i++) 
       profs[i].interrupt(); 
      teachAssist.interrupt(); 
      for(int i = 0; i < numProfs; i++) 
       profs[i].join(); 
      teachAssist.join(); 
     } 
     catch (InterruptedException e) {} 
    } 
} 

任何幫助,將不勝感激!

+1

而不是在特定的方法上使用'synchronized',你可能會更好地使用'Semaphore'來控制何時允許生產者線程填充緩衝區。 – CodeBlind

+0

信號量更容易。我不得不寫2個實驗室。一個使用信號量,另一個使用同步類。信號量很容易,但是這個給了我一些問題。 – TylerGBrooke

回答

-1

可能導致錯誤的一件事是您正在同步訪問一個資源的兩種方法。不要在方法上同步,請嘗試同步Objectbuf。這是一個問題,因爲多個線程正在修改countbuf的元素。
讓我知道如果這需要一個例子來說明競爭條件如何工作。