This example demonstrates a multi-threaded program that must share a resource between threads. Each thread will be required to obtain an exclusive lock on the shared resource to avoid a potentially disastrous conflict.
We will create two threads, one called MissileFactory and one called MissileLauncher.
The two threads are highly cohesive (they represent a single and clear purpose).
The two threads are loosly coupled (they know nothing about each other other than what is available through their public API)
The concept we present is simple. The missile factory class creates missiles at a certain speed. The job of the missile launcher class is to launch the missiles as they become available. The shared resource will be an List that holds missiles.
We will have to synchronize the shared resource. If the Missile Factory were to create a missile at the same time the Missile Launcher was trying to launch a missile, they would both be manipulating the List Object simultaneously and the result would be unpredictable and potentially dangerous.
Next, the MissileLauncher needs some way of knowing if, or when, a missile is available for launch. The missile factory is slow. A new missile is generated every 1000 ms. However, the missile launcher has no delay. We need a way for the Missile Factory and the Missile Launcher to communicate. We can do this using the wait() and notify() methods.
Our Tester class will instantiate the missile list, the missile factory, and the missile launcher. The list will be passed into the factory and launcher threads through the objects constructor.
Tester.java
import java.util.*; public class Tester{ public static void main(String[] args){ List missiles = new ArrayList (); MissileFactory missileFactory = new MissileFactory(missiles); Thread missileFactoryThread = new Thread(missileFactory); missileFactoryThread.start(); MissileLauncher missileLauncher = new MissileLauncher(missiles); Thread missileLauncherThread = new Thread(missileLauncher); missileLauncherThread.start(); } }
The missile factory class creates a missile every 1000ms. We simulate this by causing the thread to sleep before adding a new missile to the list. Notice the synchronized code block. We obtain a lock on the missiles list object and for the duration of the code block have exclusive access to it. After a new missile is added to the list, we call notify() on the object. This lets any other threads that may be waiting for access to the object know that it is now available.
MissileFactory.java
import java.util.*; public class MissileFactory implements Runnable{ private String[] cities = {"CityA","CityB","CityC"}; private List missiles; public MissileFactory(List missiles){ this.missiles = missiles; } public void run(){ while(true){ System.out.println("Creating a new Missile...\n"); try{ Thread.sleep(1000); }catch(InterruptedException e){ e.printStackTrace(); } String target = this.cities[(int)(Math.random()*cities.length)]; synchronized(missiles){ missiles.add(new Missile(target)); System.out.println(" Missile Created. Target: " + target + " (" + missiles.size() + ")\n"); missiles.notify(); } } } }
The missile launcher thread simply arms and launches the missiles in the list. However, we don't want to attempt to launch a missile from the top of the list if no missile is available. Doing so would result in a null pointer exception. The solution is to call wait() on the object. This basically pauses the thread until the object we are waiting calls notify(). We do this from the factory thread, letting the launcher thread know that a missile has just been added to the list.
MissileLauncher.java
import java.util.*; public class MissileLauncher implements Runnable{ private List missiles; public MissileLauncher(List missiles){ this.missiles = missiles; } public void run(){ while(true){ System.out.println("\tArming Missile...\n"); synchronized(missiles){ while(missiles.isEmpty()){ try{ missiles.wait(); }catch(InterruptedException e){ e.printStackTrace(); } } Missile m = missiles.get(0); missiles.remove(0); m.setArmed(true); m.launch(); } } } }
Finally, a simple Missile class. Objects of this class are added to the list
Missile.java
public class Missile{ private String target; private boolean armed; public Missile(String target){ this.target = target; } public void setArmed(boolean armed){ this.armed = armed; } public void launch(){ System.out.println("\t\tMissile Launched!\n"); } }
Compile these and run the Tester so see the demo in action.





