I am trying to implement an elevator simulator with Person and Elevator threads that share data in an ElevatorController class. My general implementation is that I have each Person store a controller variable, and from there, they request a ride in the elevator(current floor to some other floor). The controller keeps track of the requests, and the Elevator threads ask the controller for a new assignment(which floors to stop at and direction), which it generates based on the requests. The part I am having trouble with is the notification that the doors are open on a floor. I have tried putting a boolean array in the ElevatorController and have the Person threads call wait() (within a synchronized block on controller.areDoorsOpen) and then calling notifyAll on the areDoorsOpen array from the controller but I keep getting IllegalMonitorStateExceptions. My idea was that when the Person threads are notified (controller does so when it changes an entry in the areDoorsOpen array), they check the boolean array to see if the door is open on their floor (or if they are in the elevator, on their destination floor) and enter (or exit) the elevator or continue waiting. My question is why am I getting this exception on the wait() call in the person runnable.
Edit: The relevant code is
In the person Runnable,
private void waitForElevator() {
synchronized (controller.areDoorsOpenOn) {
System.out.printf("Person %d is waiting on floor %d to go to floor %d.\n", ID, currentFloor, destinationFloor);
while(!controller.areDoorsOpenOn[currentFloor]) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
In the controller class,
public boolean[] areDoorsOpenOn = new boolean[numberOfFloors];
public void notifyOpenDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = true;
notifyAll();
}
}
public void notifyClosedDoors(int floor) {
synchronized (areDoorsOpenOn) {
areDoorsOpenOn[floor] = false;
notifyAll();
}
}
The Elevator threads call notifyOpenDoors if they are on a floor that is in their assignment (stored as an array of integers) and then sleep for 3 seconds and call notifyClosedDoors
Thank you in advance for your help and let me know if you need any further clarification.
The stack trace from the IllegalMonitorStateExceptions will tell you where that's coming from - an important clue.
I believe you need to rethink which objects you are calling wait() and notifyAll() on. For example, you may want to always use areDoorsOpenOn.notifyAll() and areDoorsOpenOn.wait(). Currently, you're calling wait on the Runnable, and notifyAll on the Controllers.
Related
I am currently reading about Java BlockingQueue and this example is given on many websites for a simple implementation of the BlockingQueue. The code is simple but I am a bit confused. For example lets say we fill up the queue, then we try to enqueue 3 more times. This will make the 3 threads wait. Then when we call dequeue, the code in the dequeue method will enter the second if statement and it will notify all threads. Won't this mean that the 3 threads waiting will all add nodes to the queue? That means we will have 2 more nodes than the limit? I am pretty sure I misunderstood something here so I could use some small explanation.
public class BlockingQueue {
private List queue = new LinkedList();
private int limit = 10;
public BlockingQueue(int limit){
this.limit = limit;
}
public synchronized void enqueue(Object item)
throws InterruptedException {
while(this.queue.size() == this.limit) {
wait();
}
this.queue.add(item);
if(this.queue.size() == 1) {
notifyAll();
}
}
public synchronized Object dequeue()
throws InterruptedException{
while(this.queue.size() == 0){
wait();
}
if(this.queue.size() == this.limit){
notifyAll();
}
return this.queue.remove(0);
}
}
No, only one will add a node. Notice that your wait-call in enqueue is inside a loop:
while(this.queue.size() == this.limit) {
wait();
}
All three threads are notified but only one thread can be in the synchronized-block. The first thread to enter the block adds a node, so the queue is full again. The other both threads enter the block (one after another) but see the queue being full again, which will put them right into waiting state again as that's the loop-condition.
You can imagine a wait to be an exit and entrace point of a synchronized-block. When a thread enters wait, then the corresponding lock is released. A thread that has been waiting in a wait and is notified, is trying to acquire the corresponding lock for the critical section again and blocks if it is currently in use. So only one of the notified three threads can enter at a time.
Note that wait() from .enqueue() is inside loop. Any awoken thread will re-check permit to add an element and since only single thread can execute synchronized method at a time, there will be no problem - one thread gets lucky to insert an element, others continue to wait after failed re-check.
Create a program that simulates training at an athletic stadium,
there is one track in the stadium that can be used by up to 5 people at a time
and the coach does not allow that number to exceed, but when some of the athletes finish their run (2sec)
and free up space then notify other athlete for running.
After 2 seconds, all processes are frozen
My question is, could anyone explain to me why something like this does not work and how to handle this problem?
class JoggingTrack {
public int numOfAthlete;
public JoggingTrack() {
this.numOfAthlete = 0;
}
#Override
public String toString() {
return "\nNumber of Athlete: " + numOfAthlete + "\n";
}
}
class Athlete extends Thread {
private JoggingTrack track;
private boolean running;
public Athlete(JoggingTrack s) {
this.track = s;
this.running = false;
}
public synchronized boolean thereIsSpace() {
if(track.numOfAthlete < 5) {
return true;
}
return false;
}
public synchronized void addAthlete() {
track.numOfAthlete++;
this.running = true;
}
public synchronized void removeAthlete() {
track.numOfAthlete--;
this.running = false;
}
#Override
public void run() {
try {
while(true) {
while(!this.thereIsSpace()) {
wait();
}
while(!this.running) {
addAthlete();
sleep(2000);
}
while(this.running) {
removeAthlete();
notify();
}
}
} catch (Exception e) {
}
}
}
public class Program {
static JoggingTrack track;
static Athlete[] a;
public static void main(String[] args) {
track = new JoggingTrack();
a = new Athlete[10];
for(int i = 0; i < 10; i++) {
a[i] = new Athlete(track);
a[i].start();
}
while(true) {
try {
System.out.println(track);
Thread.sleep(500);
} catch (Exception e) {
}
}
}
}
A lot of issues with this.
Your methods are in the wrong place. The synchronized keyword synchronizes on an instance of the class, not across multiple instances. So your remove and add functions on different athletes would cause race conditions. These functions should be moved to the Track object, because all athletes are using the same track (so should your isThereSpace function). At the same time, you should not be directly accessing the member variables of Track in Athlete, use a getter for it instead.
Secondly, you use of wait and notify are wrong. They leave lots of holes for race conditions, although it may work most of the time. And this isn't really a good place for using them- a counting semaphore in the Track class would be a better solution- its exactly what counting semaphores are made for. Look at the Semaphore class for more details. Its basically a lock that will allow N owners of the lock at a time, and block additional requesters until an owner releases it.
Your threads are waiting forever, because they are waiting on some object (their instance itself), and nobody ever notify-es them, using the right instance.
One way to fix this is to have all athlete-s to synchronize/wait/notify on the same object, in example, the JoggingTrack. So that an athlete will wait on the track with track.wait(), and when an athlete is done running, it will call track.notify() , and then a waiting athlete will be waken up.
Then there are other issues as noted by Gabe-
Once you fix the first issue, you will find the race conditions- eg. too many threads all start running even though there are some checks (thereIsSpace) in place.
My question is, could anyone explain to me why something like this does not work and how to handle this problem?
Debugging multithreaded programs is hard. A thread-dump might help and println-debugging might also be helpful however they can cause the problem to migrate so it should be used with caution.
In your case, you are confusing your objects. Think about
Athlete.thereIsSpace() and Athlete.addAthlete(...). Does that make any sense? Does an athlete have space? Do you add an athlete to an athlete? Sometimes the object names don't help you make these sorts of evaluations but in this case, they do. It is the JoggingTrack that has space and that an athlete is added to.
When you are dealing with multiple threads, you need to worry about data sharing. If one thread does track.numOfAthlete++;, how will other threads see the update? They aren't sharing memory by default. Also ++ is actually 3 operations (read, increment, write) and you need to worry about multiple threads running the ++ at the same moment. You will need to use a synchronized block to ensure memory updates or use other concurrent classes such as AtomicInteger or a Semaphore which take care of the locking and data-sharing for you. Also, more generally, you really should not modify another object's fields in this way.
Lastly, you are confused about how wait/notify work. First of all, they only work if they are inside a synchronized block or method so I think the code you've posted won't compile. In your case, the thing that the multiple Athletes are contending for is the JoggingTrack, so the track needs to have the synchronized keyword and not the Athlete. The Athlete is waiting for the JoggingTrack to get space. No one is waiting for the athlete. Something like:
public class JoggingTrack {
public synchronized boolean thereIsSpace() {
return (numOfAthletes < 5);
}
public synchronized void addAthlete() {
numOfAthletes++;
}
...
Also, like the ++ case, you need to be really careful about race conditions in your code. No, not jogging races but programming races. For example, what happens if 2 athletes both go to do the following logic at precisely the same time:
while (!track.thereIsSpace()) {
track.wait();
}
addAthlete();
Both athletes might call thereIsSpace() which returns true (because no one has been added yet). Then both go ahead and add themselves to the track. That would increase the number of athletes by 2 and maybe exceed the 5 limit. These sorts of races-conditions happen every time unless you are in a synchronized block.
The JoggingTrack could instead have code like:
public synchronized void addIfSpaceOrWait() {
while (numOfAthletes >= 5) {
wait();
}
numOfAthletes++;
}
Then the althetes would do:
track.addIfSpaceOrWait();
addAthlete();
This code has no race condition because only one athlete will get the synchronized lock on the track at one time -- java guarantees it. Both of them can call that at the same time and one will return and the other will wait.
Couple other random comments:
You should never do a catch (Exception e) {}. Just doing an e.printStackStrace() is bad enough but not seeing your errors is really going to confuse you ability to debug your program. I will hope you just did that for your post. :-)
I love the JoggingTrack object name but whenever you reference it, it should be joggingTrack or maybe track. Be careful of JoggingTrack s.
An Athlete should not extend thread. It isn't a thread. It should implement Runnable. This is a FAQ.
I am fairly new to JAVA and especially concurrency, so probably/hopefully this is fairly straight forward problem.
Basically from my main thread I have this:
public void playerTurn(Move move)
{
// Wait until able to move
while( !gameRoom.game.getCurrentPlayer().getAllowMove() )
{
try {
Thread.sleep(200);
trace("waiting for player to be available");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
gameRoom.getGame().handle(move);
}
gameRoom.getGame() is on its own thread.
gameRoom.getGame().handle() is synchronized
gameRoom.game.getCurrentPlayer() is on a varible of gameRoom.getGame(), it is in the same thread
allowMoves is set to false as soon as handle(move) is called, and back to true once it has finished processing the move.
I call playerTurn() multiple times. I actually call it from a SmartFoxServer extension, as and when it receives a request, often in quick succession.
My problem is, most times it works. However SOMETIMES it is issuing multiple handle(move) calls even though allowMoves should be false. Its not waiting for it to be true again. I thought its possible that the game thread didn't have a chance to set allowMoves before another handle(move) was called. I added volatile to allowMoves, and ensured the functions on the game thread were set to synchronized. But the problem is still happening.
These are in my Game class:
synchronized public void handle(Object msg)
{
lastMessage = msg;
notify();
}
synchronized public Move move() throws InterruptedException
{
while (true)
{
allowMoves = true;
System.out.print(" waiting for move()...");
wait();
allowMoves = false;
if (lastMessage instanceof Move)
{
System.out.print(" process move()...");
Move m = (Move) lastMessage;
return m;
}
}
}
public volatile boolean allowMoves;
synchronized public boolean getAllowMoves()
{
return allowMoves;
}
As I said, I am new to this and probably a little ahead of myself (as per usual, but its kinda my style to jump into the deep end, great for a quick learning curve anyway).
Cheers for your help.
Not sure if this will help, but what if you will use AtomicBoolean instead of synchronized and volatile? It says that it is lock-free and thread-safe.
The Problem is you are using synchronized method on two different objects.
gameRoom.game.getCurrentPlayer().getAllowMove()<-- This is synchronized on
CurrentPlayer instance.
gameRoom.getGame().handle(move)<-- This is synchronized on `gameRoom.getGame()`
This is your issue. You don't need synchronized keyword for getAllowMoves since field is volatile as volatile guarantees visibility semantics.
public boolean getAllowMoves() {
return allowMoves;
}
there is the primitive, dedicated for resource management - Semaphore
you need to
create semaphore with permits set to 1
use acquire when looking for a move
use release after move is complete
so you will never face that 2 concurrent invocations of handle method appear.
I’m writing a Tetris-like game for Android and I’m trying to implement the “real-time part”. I have something which seems to work, but I want to be sure that my implementation is correct.
What I want is:
The shapes are going down at a fixed rate (say that I want to wait n milliseconds each time the y of the shape is decremented)
The player can drop the shape at any time and the timer waiting for the n milliseconds must then be immediately interrupted and start again only for the next shape
When the shape is droped or when the shape cannot go down anymore, the game waits m milliseconds before creating another shape
The system have to be able to stop the thread at any time
What I am doing is the following (the system can stop the thread with interrupt()):
class TetrisThread extends Thread {
private int n = 3000; // for testing purposes, in the real game n will be smaller ;)
private int m = 1000;
#Override
public void run() {
doDraw();
while(!interrupted())
{
try {
synchronized (this) {
wait(n);
}
doPhysics();
doDraw();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
// This method is the one which will drop the shape, it is called from another thread
synchronized public boolean onTouch([…]) {
[…]
// The shape has to be dropped
dropShape();
notify();
[…]
}
private void doPhysics() throws InterruptedException {
[…]
// The shape cannot go down or has been dropped
sleep(m);
createNewShape();
[…]
}
}
In particular, the part synchronized(this) { wait(n); } looks funny because if I understand correctly this will take a lock on this and release it immediately.
But wait() requires to be used in a synchronized(this) block (why?) and I cannot either synchronize the whole run() method, because then if I try to drop three times the shape during the sleep(m) call, then the three next shapes will be automatically dropped (which is not what I want).
Does this seem correct to you?
Do you have any correction, advice, or remark?
Thank you :-)
The wait() method is used to make the current running thread to wait the object invoking wait() invoke notify() (in this case this). The synchronized(this) part needed to make sure only one thread at that time accessing this.
You can't synchronize the whole run() method, because the run() is from the parent (Thread) class and the parent didn't use synchonized in the declaration.
I don't know how to solve your other problem because I don't get how your program works right now.
I am trying to program a game in which I have a Table class and each person sitting at the table is a separate thread. The game involves the people passing tokens around and then stopping when the party chime sounds.
how do i program the run() method so that once I start the person threads, they do not die and are alive until the end of the game
One solution that I tried was having a while (true) {} loop in the run() method but that increases my CPU utilization to around 60-70 percent. Is there a better method?
While yes, you need a loop (while is only one way, but it is simplest) you also need to put something inside the loop that waits for things to happen and responds to them. You're aiming to have something like this pseudocode:
loop {
event = WaitForEvent();
RespondToEvent(event);
} until done;
OK, that's the view from 40,000 feet (where everything looks like ants!) but it's still the core of what you want. Oh, and you also need something to fire off the first event that starts the game, obviously.
So, the key then becomes the definition of WaitForEvent(). The classic there is to use a queue to hold the events, and to make blocking reads from the queue so that things wait until something else puts an event in the queue. This is really a Concurrency-101 data-structure, but an ArrayBlockingQueue is already defined correctly and so is what I'd use in my first implementation. You'll probably want to hide its use inside a subclass of Thread, perhaps like this:
public abstract class EventHandlingThread<Event> extends Thread {
private ArrayBlockingQueue<Event> queue = new ArrayBlockingQueue<Event>();
private boolean done;
protected abstract void respondToEvent(Event event);
public final void postEvent(Event event) throws InterruptedException {
queue.put(event);
}
protected final void done() {
done = true;
}
public final void run() {
try {
while (!done) {
respondToEvent(queue.take());
}
} catch (InterruptedException e) {
// Maybe log this, maybe not...
} catch (RuntimeException e) {
// Probably should log this!
}
}
}
Subclass that for each of your tasks and you should be able to get going nicely. The postEvent() method is called by other threads to send messages in, and you call done() on yourself when you've decided enough is enough. You should also make sure that you've always got some event that can be sent in which terminates things so that you can quit the game…
I would look into Locks and Conditions. This way you can write code that waits for a certain condition to happen. This won't take a lot of CPU power and is even much more efficient and better performing than sleeping .
To make a thread run for an infinite time:
final Object obj = new Object();
try {
Thread th = new Thread(new Runnable() {
public void run() {
synchronized(obj) {
try {
System.out.println("Waiting");
obj.wait();
System.out.println("Done waiting");
}catch(Exception ex) {
ex.printStackTrace();
}
}
}
});
th.start();
System.out.println("Waiting to join.");
// Dont notify; but wait for joining. This will ensure that main thread is running always.
th.join();
System.out.println("End of the Program");
} catch(Exception ex) {
ex.printStackTrace();
}
You may add Thread.sleep() with appropriate time to minimize useless loop iterations.
Another solution is using synchronization. While threads are not required to do anything, they enter into a sleeping state on a monitor using the wait() method, and then when the turn comes, required thread is woken up by the notify() method.
Actor model seems suitable for this scenario. Each person sitting on the table and the table itself can be modelled as actors and the event of passing the tokens and starting and stopping of the game can be modelled as messages to be passed between the actors.
As a bonus, by modelling the scenario as actors you get rid of explicit manipulation of threads, synchronization and locking.
On JVM I will prefer using Scala for modelling actors. For Java you can use libraries like Kilim. See this post for a comparison of Actor model related libraries in Java.
One Way is to use while loop but keep a check i.e
while(true){
if(condition!=true){
Thread.sleep(time);
}else{
break;
}
}
This way if your condition says game is not over it will keep person thread at sleep and memory consumption will be very low.
You should test for a condition in the while loop:
while (!gameOver)
{
do_intersting_stuff();
}
Heavy CPU load is typical for busy wait. Is your loop actually just checking a flag over and over, like
while (!gameOver)
{
if (actionNeeded)
{
do_something();
}
}
you might change to another notification system to sleep and wake up, as this just burns CPU time for nothing.