Reputation: 41
I am trying to simulate a parking lot entry system that contains 2 floors of 20 spaces and 2 entries and 2 exits. I am using Threads in Java, and I have tried to use thread.wait()
and thread.sleep
but they don't help in making a thread run after another thread is over.
This is what I have come up with so far:
ShardedDataThread.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class SharedDataThread extends Thread {
private SharedData mySharedData;
private String myThreadName;
public int L1 = 20;
public int L2 = 20;
//Setup the thread
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
SharedDataThread(String name, SharedData sharedstuff) {
super(name);
mySharedData=sharedstuff;
myThreadName=name;
}
//This is called when "start" is used in the calling method
public void run() {
while(true){
System.out.println("Entry or Exit?");
String input = null;
try {
input = br.readLine();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (input.equalsIgnoreCase("entry")) {
try {
// Acquire the lock using the acquireLock() method
// The thread will pause here on wait() until it gets a lock
mySharedData.acquireLock();
//use park method to occupy one space
this.park(); // Increment the number of reads
mySharedData.releaseLock();
}
catch(InterruptedException e) {
System.err.println("Failed to get lock when reading:"+e);
}
}
else {
try {
mySharedData.acquireLock();
System.out.println(myThreadName+" is writing");
exit(); // INCREMENT ONE SPOT
mySharedData.releaseLock(); // releases the lock
}
catch(InterruptedException e) {
System.err.println("Failed to get lock when writing:"+e);
}
}
System.out.println("L1 has : "+L1+" "+"L2 has: "+" "+L2);
}
//while ends
}
//State method
public void park() {
if (L1>0 && L1<=20){
L1= L1-1;
}
else if (L1==0 && L2<=20 && L2>0){
L2= L2-1;
}
else if (L1==0 && L2==0){
System.out.println("No Spaces Left");
}
}
public void exit() {
if (L1<20) {
L1 = L1 +1;
} else if (L2<20) {
L2 = L2+1;
}
}
public static void main(String[] args) throws InterruptedException {
SharedData mySharedData = new SharedData();
SharedDataThread myThread1 = new SharedDataThread("Entry1", mySharedData);
//SharedDataThread myThread2 = new SharedDataThread("Entry2", mySharedData);
//SharedDataThread myThread3 = new SharedDataThread("Exit1", mySharedData);
//SharedDataThread myThread4 = new SharedDataThread("Exit2", mySharedData);
// Now start the threads executing
myThread1.start();
//myThread1.join();
//myThread2.start();
//myThread2.join();
//myThread3.start();
//myThread3.join();
//myThread4.wait();
}
}
SharedData.java
public class SharedData {
private boolean accessing=false; // true a thread has a lock, false otherwise
// attempt to acquire a lock
public synchronized void acquireLock() throws InterruptedException{
Thread me = Thread.currentThread();
while (accessing) {
wait();
}
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
}
}
Upvotes: 1
Views: 113
Reputation: 182893
You're thinking about the problem wrong. Don't think about waiting for a thread to do something after a thread is done. Think about doing something after some work is done. That means that the work has to be waitable.
Upvotes: 0
Reputation: 27210
This never makes any sense:
myThread1.start();
myThread1.join();
It never makes any sense to start a thread and then immediately wait for it to finish. The entire point of having threads is that different threads can be doing different things at the same time.
If there isn't anything else that the caller wants to do while myThread1
is running, then there is no reason to create myThread1
. The caller should just do whatever it is that myThread1
would have done at that point.
Don't use threads to model objects in a simulation. Use threads to do work. Usually, that means, use a thread pool such as java.util.concurrent.ThreadPoolExecutor
to perform tasks.
If you want your simulation to run in real time, don't use threads that sleep()
. Use a scheduler such as java.util.concurrent.ScheduledThreadPoolExecutor
to perform delayed tasks.
Upvotes: 1