Imagine you have two threads. left thread and right thread. the left thread is responsible for creating work objects, and the right thread is responsible for their work.
when the left thread has finished creating the object, it places the object in a place where the correct thread can find it. this is a variable, let it be called w (for the worker), and for simplicity let me say that it is somehow accessible globally.
the right thread is a loop. he checks if w is not empty. if w actually has any null values, then the do method is called on it.
the working class is as follows:
public class Worker { private int strength; private float speed; private String name; private String specialty; public Worker(int str, float spd, String n, String spc) { strength = str; speed = spd; name = n; specialty = spc; } public void do() { System.out.println("Worker " + name + " performs " + strength + " " + specialty + " at " + speed + " times per minute."); } }
so it looks something like this (I tried to illustrate the two threads by setting their respective commands in one column each. I hope this is clear. Remember that only one thread is active at once, so there are always only instructions in one column at a time)
left thread | right thread ----------------------------------------------------|----------------------------------------------------- | Worker newWorker = new Worker( | ...right thread sleeps... 4, | . 5.2f, | . "mmayilarun", | . "multithreaded programming" | . ); | . -- control jumps to constructor of Worker -- | . strength = str | . speed = spd; | !!right thread wakes up and takes the focus!! | | if(w == null) { | Thread.sleep(500); | } else { | //this doesn't happen, since w is still null | } | | ...right thread goes back to sleep... name = n; | . specialty = spc; | . -- control exits constructor of Worker -- | . w = newWorker; | !!right thread wakes up and takes the focus!! | | if(w == null) { | //this doesn't happen, since w is NOT null anymore | } else { | w.do(); | } |
everything is fine in this scenario. set of left threads w after completion of the constructor of the worker. but isn't it stupid to do so? imagine the savings we can make if we put this w = instanceOfWorker call inside a working constructor. then we would not have to worry about remembering the actual value of w.
The new worker constructor is as follows:
public Worker(int str, float spd, String n, String spc) { w = this; strength = str; speed = spd; name = n; specialty = spc; }
Now the code stream may look like this:
left thread | right thread ----------------------------------------------------|----------------------------------------------------- | Worker newWorker = new Worker( | ...right thread sleeps... 4, | . 5.2f, | . "mmayilarun", | . "multithreaded programming" | . ); | . -- control jumps to constructor of Worker -- | . w = this; // danger!! | . strength = str; | . speed = spd; | !!right thread wakes up and takes the focus!! | | if(w == null) { | //this doesn't happen, since w is NOT null at this point | } else { | w.do(); //here, w is not yet a fully initialized object, | //and the output is not the expected (if it works at all) | } | | ...right thread goes back to sleep... name = n; | . specialty = spc; | . -- control exits constructor of Worker -- |
oracle has a more complex example with a set of objects called "instances". that is the only difference.