aspose file tools*
The moose likes Threads and Synchronization and the fly likes Help make this simple example thread safe Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Threads and Synchronization
Bookmark "Help make this simple example thread safe" Watch "Help make this simple example thread safe" New topic
Author

Help make this simple example thread safe

Bruno De Rye
Greenhorn

Joined: Jun 04, 2012
Posts: 2
Hi all, I am trying to learn threads.

I did read a few tutorials and made myself a small example to try and understand thread synchronization. It's an airline simulation, basically I have 10 planes (threads) which try to land at an airport which admits only 3 at a same time. The idea is the program should crash if more than this number of planes is found to have landed at the same time.

My questions are:
1) How can I modify this code so that the airport will correctly prevent more than 3 planes from entering. I tried a few things and haven't found the solution yet. When you run it, at some point it throws the IllegalStateException which signals you had an "unsafe" airport situation.
2) The way I check this condition is using another thread, SafetyAgent. Is there a more elegant way of checking this? I wasn't exactly sure when a condition would arise that the data in the airport was inconsistent (more than 3 planes landed) so I made this thread which checks the airport every nth millisecond to see if such condition happens.
3) I stop the program (threads) using a flag (running = false). Is it ok or should I implement it using interrupts? I looked at interrupts but my impression is that it is a bit cumbersome in most cases, maybe I'm wrong.

Here's the full code (should run on Java7):



Thanks
Anayonkar Shivalkar
Bartender

Joined: Dec 08, 2010
Posts: 1506
    
    5

Hello Bruno De Rye,

Welcome to CodeRanch!

Good to see that you've used code tags in your very first post

Now, coming to your problem -

You've (almost) taken a good care of synchronization, however, at one place, there is a possibility (which is evident from the exception) that the code is not properly synchronized.
Imagine below scenario:
There are 10 airplane thread. All of them invoke canLand method on airport. This method will return true. Of course, only one thread will be able to enter in that method at a time, but still it is possible to get true value for all airplane threads.

Now, all of the threads try to invoke visit method.
Airplane 1 comes, increase the nbPlanes variable, and wait for some time.
Airplane 2 comes, increase the nbPlanes variable, and wait for some time.
Airplane 3 comes, increase the nbPlanes variable, and wait for some time.
Airplane 4 comes, increase the nbPlanes variable, and wait for some time.

Now, the safety agent wakes up and says, OMG! there are 4 planes on airport! Let's throw a nice exception

I hope you got the scenario, and if you've written this code on your own, then I guess you will be able to fix this issue.

Hint : its a typical scenario - all of the 10 airplanes checked and found that airport is empty - so all of them started to land. However, when airplane count started increasing, other airplane were not notified (or, actually speaking, they already checked and found that airplane was empty).

However, I would like to suggest altogether another approach. Instead of treating all the airplanes as threads, simply follow the producer consumer model:
1) All the airplanes are simple objects, not threads.
2) There will be two threads - one which handles landing (we'll call it 'lander') and another which handles take-offs (we'll call it 'flyer').
3) If airport is empty, flyer will be inactive and lander will be active.
4) If airport is already having 'threshold' number of airplanes (say 3), then flyer will be active and lander will be inactive.
5) Lander will be active only if there are 0-2 airplanes on the airport - i.e. there is at least one place on airport.
6) Flyer will be active only if there are any airplanes on the airport - i.e. number_of_landed_airplanes > 0

I hope this helps.


Regards,
Anayonkar Shivalkar (SCJP, SCWCD, OCMJD, OCEEJBD)
Bruno De Rye
Greenhorn

Joined: Jun 04, 2012
Posts: 2
Hi Anayonkar, thanks for your reply and help. Ok I think I got it, so yea there's no blocking between checking if there's room and actually launching the landing procedure. I can see how in real life that'd prove dangerous too ;-)

So I should probably have some kind of reservation instead, where the airport reserves a spot for the specific plane (ex. plane #0 asked for landing, check if room and reserve spot for that plane only), or perhaps re-check again in my visit() method and simply return false for example if landing was denied (think of it as a last minute check).

In terms of your two threads approach, I can understand what you mean but I'm not sure if I really understand then how could I correctly simulate each plane having its own control or life if you will and deciding in a kind of random way when they want to land. Also I actually want (didn't mention this before) to build a little GUI example around this eventually to play with both threads, GUI code (I want to tackle a bit of JavaFX eventually) and have the planes fly around randomly while waiting for the airport clearance (and maybe do a little bit of crash visual FX to simulate what happens when threads arent synched lol).

Also just to clarify, does your suggestion come from an angle of performance (ie having as many threads as planes isn't a good scalable idea?). It just seemed natural to make each plane its own thread, but maybe that isn't good practice? Thanks again.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Bruno De Rye wrote:Hi Anayonkar, thanks for your reply and help. Ok I think I got it, so yea there's no blocking between checking if there's room and actually launching the landing procedure. I can see how in real life that'd prove dangerous too ;-)

So I should probably have some kind of reservation instead, where the airport reserves a spot for the specific plane (ex. plane #0 asked for landing, check if room and reserve spot for that plane only), or perhaps re-check again in my visit() method and simply return false for example if landing was denied (think of it as a last minute check).


If you wanted to take this approach, you can look at the Java 7 API. There is a near perfect class for what you want in the java.util.concurrent package. Have a look and see if you can find it. If you can't let us know and we can help you narrow down on the correct thread-safe permission type counting object.


In terms of your two threads approach, I can understand what you mean but I'm not sure if I really understand then how could I correctly simulate each plane having its own control or life if you will and deciding in a kind of random way when they want to land. Also I actually want (didn't mention this before) to build a little GUI example around this eventually to play with both threads, GUI code (I want to tackle a bit of JavaFX eventually) and have the planes fly around randomly while waiting for the airport clearance (and maybe do a little bit of crash visual FX to simulate what happens when threads arent synched lol).

Also just to clarify, does your suggestion come from an angle of performance (ie having as many threads as planes isn't a good scalable idea?). It just seemed natural to make each plane its own thread, but maybe that isn't good practice? Thanks again.


Indeed, primarily this is a performance issue, and if you start putting GUI into then it becomes more so. Too many Threads and you have too many things trying to hog CPU and everything starts to slow down. Also, this becomes a design issue as well: it is not so good to design a Thing (Airplane) as an Action (Runnable). Rather you design the Thing as a normal Object, and have some handler or controller execute short concise Actions on the Thing (an Air Traffic Controller landing a Airplane, or Ground Controller launching the Airplane).

To execute your entire system, I could see it happening in 4 threads, but maybe fewer:
1) The GUI thread
2) A Landing Controller thread
3) A Take Off Controller thread
4) An In Flight Controller thread

So how to implement planes moving around independently? Each plane could have a position, speed, direction of travel, and a flag if it wants to land. The GUI reads its position and paints it in place. The Landing Controller listens to the 'I want to land' flags and makes sure planes get in line to land and puts them on the Ground when there is room. The Take Off Controller looks at the Ground and puts airplanes in the air when it is their turn to launch, and the Flight Controller resets all plane's positions based on their speed and direction.


Steve
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Help make this simple example thread safe