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;
}
}
各スレッドを識別するハンドラを作成する必要があると思いますが、どのようにすればよいか分かりません。