2017-11-22 12 views
0

私は駐車場管理システムを作成しています。そこでは、クライアントを表す4つのスレッド(2つの入口クライアントと2つの出口クライアント)があります。駐車場に空きスペースがない場合、サーバーは待機中の顧客を待ち行列に入れ、自動車が出ると待ち行列のメンバーを取り除きます。特定のスレッドにデータを送信するにはどうすればよいですか?

車が出てデキューするときに問題が発生します。デキューされたクライアントに、駐車場にアクセスできるようにする方法を教えてください。

次のように私のプログラムが実行設定されている:

Serverクラス:

public class Server { 

public static void main(String[] args) throws IOException { 
    //Create the shared objects in the global scope... 
    int groundFloor = 20; 
    int firstFloor = 20; 
    SharedState SharedStateObject = new SharedState(groundFloor,firstFloor); 

    //Sets up the server socket on port 4444 
    ServerSocket serverSocket = null; 
    try 
    { 
     serverSocket = new ServerSocket(4444); 
     System.out.println("Car Park Server started." + "\n"); 
    } 
    catch (IOException e) { 
     System.err.println("Could not start server on specified port."); 
     System.exit(-1); 
    } 

    //Got to do this in the correct order with only four clients! 
    while (true){ 
     new ServerThread(serverSocket.accept(), "GroundFloorEntrance", SharedStateObject).start(); 
     new ServerThread(serverSocket.accept(), "FirstFloorEntrance", SharedStateObject).start(); 
     new ServerThread(serverSocket.accept(), "GroundFloorExit1", SharedStateObject).start(); 
     new ServerThread(serverSocket.accept(), "GroundFloorExit2", SharedStateObject).start(); 
     break; 
    } 
    serverSocket.close(); 
} 
} 

ServerThreadクラス

@SuppressWarnings("unused") 
public class ServerThread extends Thread { 

    private Socket clientSocket = null; 
    private SharedState mySharedStateObject; 
    private String myServerThreadName; 
    private int mySharedVariable; 

    //Setup the thread 
    public ServerThread(Socket clientSocket, String ServerThreadName, SharedState SharedObject) 
    { 
     super(ServerThreadName); 
     this.clientSocket = clientSocket; 
     mySharedStateObject = SharedObject; 
     myServerThreadName = ServerThreadName; 
    } 

    public void run() { 
     try { 
      System.out.println(myServerThreadName + " connected."); 
      PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
      BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); 
      String inputLine, outputLine; 

      while ((inputLine = in.readLine()) != null) { 
       // Get a lock first 
       try { 
        mySharedStateObject.acquireLock(); 
        outputLine = mySharedStateObject.processInput(myServerThreadName, inputLine); 
        out.println(outputLine);      
        mySharedStateObject.releaseLock(); 
       } 
       catch(InterruptedException e) { 
        System.err.println("Failed to get lock when reading:"+e); 
       } 
      } 

      out.close(); 
      in.close(); 
      clientSocket.close(); 

      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     } 

}

sharedStateのクラス

@SuppressWarnings("unused") 
public class SharedState extends Thread{ 

private SharedState mySharedObj; 
private String myThreadName; 
private int totalSpaces; 
private int groundSpaces; 
private int firstSpaces; 
private boolean accessing=false; // true a thread has a lock, false otherwise 
private int threadsWaiting = 0; // number of waiting writers 
JFrame Notification = new JFrame(); 

@SuppressWarnings("rawtypes") 
private List queue = new LinkedList(); 

// Constructor 
SharedState(int groundFloor, int firstFloor) { 
    groundSpaces = groundFloor; 
    firstSpaces = firstFloor; 
} 

//Queue organiser 
@SuppressWarnings("unchecked") 
public synchronized void enqueue(Object item) throws InterruptedException 
{ 
    queue.add(item); 
} 
public synchronized Object dequeue() throws InterruptedException 
{ 
    return this.queue.remove(0); 
} 

//Attempt to aquire a lock 
public synchronized void acquireLock() throws InterruptedException{ 
    Thread me = Thread.currentThread(); // get a ref to the current thread 
    ++threadsWaiting; 
    while (accessing) { // while someone else is accessing or threadsWaiting > 0 
     //wait for the lock to be released - see releaseLock() below 
     wait(); 
    } 
    // nobody has got a lock so get one 
    --threadsWaiting; 
    accessing = true; 
} 

// Releases a lock to when a thread is finished 
public synchronized void releaseLock() { 
    //release the lock and tell everyone 
    accessing = false; 
    notifyAll(); 
    Thread me = Thread.currentThread(); // get a ref to the current thread 
} 

public synchronized String processInput(String myThreadName, String theInput) throws InterruptedException 
{ 
    String theOutput = null; 

    // Check what the client said  
    if (theInput != null) 
    {   
     //Correct request 
     if(myThreadName.equals("GroundFloorEntrance")) 
     { 
      if(groundSpaces > 0) 
      { 
       groundSpaces--; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Access granted. Vehicle arrived on ground floor."; 
      } 
      else if (firstSpaces > 0) 
      { 
       firstSpaces--; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Access granted. Vehicle arrived on first floor."; 
      } 
      else 
      { 
       enqueue(myThreadName); 
       theOutput = "Access denied. No spaces available, please wait."; 
      } 
     } 
     if(myThreadName.equals("FirstFloorEntrance")) 
     { 
      if(firstSpaces > 0) 
      { 
       firstSpaces--; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Access granted. Vehicle arrived on first floor."; 
      } 
      else if (groundSpaces > 0) 
      { 
       groundSpaces--; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Access granted. Vehicle arrived on ground floor."; 
      } 
      else 
      { 
       enqueue(myThreadName); 
       theOutput = "Access denied. No spaces available, please wait."; 
      } 
     } 

     if(myThreadName.equals("GroundFloorExit1")) 
     { 
      if(groundSpaces == 0 && !queue.isEmpty()) 
      {    
       dequeue(); 
       theOutput = "Vehicle departed from ground floor.\nVehicle arrived from queue."; 
      } 
      else if(groundSpaces < 20) 
      { 
       groundSpaces++; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Vehicle departed from ground floor."; 
      } 
      else 
      { 
       theOutput = "No vehicles expected in the car park."; 
      } 
     } 
     if(myThreadName.equals("GroundFloorExit2")) 
     { 
      if(!queue.isEmpty()) 
      { 
       dequeue(); 
       theOutput = "Vehicle departed from first floor.\nVehicle arrived from queue."; 
      } 
      else if(firstSpaces < 20) 
      { 
       firstSpaces++; 
       totalSpaces = groundSpaces + firstSpaces; 
       theOutput = "Vehicle departed from first floor."; 
      } 
      else 
      { 
       theOutput = "No vehicles expected in the car park."; 
      } 
     } 
    } 

    //Return the output message to the Server and display all notifications 
    JOptionPane.showMessageDialog(Notification, theOutput); 
    System.out.println("\n" + theOutput + "\nGround floor spaces = " + groundSpaces + "\nFirst floor spaces = " + firstSpaces + "\nTotal spaces = " + totalSpaces + "\nQueue: " + queue); 

    return theOutput; 
} 
} 

各スレッドを識別するハンドラを作成する必要があると思いますが、どのようにすればよいか分かりません。

答えて

0

あなたはより良い利用が生成し、消費者のパターンと

ArrayBlockingQueue 

を共有データを格納するためでしょう。 プロデューサはclientSocketから読み込んでデータをキューに入れ、コンシューマはキューからデータを取り出して処理します。 アイテムをフル・キューに入れようとしているスレッドがブロックをブロックしません

関連する問題