my task is to create thread in this order: if A start->start B and C, if B start->start D. And destroy them in reverse order If D then B. If B and C then A. I hope you get it.
In my opinion, it is quite strange to use synchronized (lock)
in your run method to lock your object. The reason is that in each Thread
object has the different lock
attribute, which is belong to each object. It means you are trying to lock the different objects. Actually, it doesn't make sense.
Basically, the object that you should apply the synchronized
are any shared objects. For example, you need to count something and then you create a class object to share it in your class. In this case, it should be locked while being read or written.
In multi threading, there is no need of synchronization unless the common data is shared by multiple threads. In your case, you want to start and stop the threads in a particular order. For this, there is join method in Thread class. This link shows good example of join method.
I would like to highlight two points here:
In your case, when the condition if(thread_A.isAlive()) is executed, it is possible that the thread A may not be in running state. Hence, the control will not go into if which is not correct. To correct this behavior, in main, a while loop should implemented which waits until the thread becomes alive and so on.
2 . In your program, you have not assigned names to the threads and you are printing the name in the run() method. In this case, JVM assigns the names to threads in order of their execution e.g. first thread to execute will have name as 'Thread-0' and so on. Hence, we will not be able to identify which thread executed first. Assign the names using setName() method.
There are some flaws in your code which will make it not to work accordingly sometimes:
thread_A.start()
and then checked thread_A.isAlive()
. Now what if , thread_A is already completed before thread_A.isAlive()
condition is checked?.thread_B
and thread_C
is never started. Your application fails.thread_A
is not completed and thread_A.isAlive()
condition is passed, then starting of thread_B
before thread_C
is not always guaranteed by Java thread scheduler. Again your application fails.thread_B
starts before thread_C
and if thread_B
completes before thread_B.isAlive()
is checked then the if
condition fails and thread_D
is never started. Again your application fails.Now a point to ponder:
There is no need to check if the thread is alive after its join()
method is called. It is an unnecessary runtime overhead.
EDIT
OK, Here is the modified version of code..I hope it would let you understand the dynamics of thread:
class RobotController implements Runnable
{
private final Object lock = new Object();
private void notifyThread()
{
synchronized(lock)
{
lock.notify();
}
}
public void run()
{
synchronized(lock)
{
try
{
System.out.println(Thread.currentThread().getName() + " started");
lock.wait();
System.out.println(Thread.currentThread().getName()+ " stopped");
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
public static void main(String args[]) throws InterruptedException
{
RobotController rca = new RobotController();
RobotController rcb = new RobotController();
RobotController rcc = new RobotController();
RobotController rcd = new RobotController();
Thread thread_A = new Thread(rca,"Thread A");
Thread thread_B = new Thread(rcb,"Thread B");
Thread thread_C = new Thread(rcc,"Thread C");
Thread thread_D = new Thread(rcd,"Thread D");
thread_A.start();
while (thread_A.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_B.start();
thread_C.start();
while (thread_B.getState() != Thread.State.WAITING && thread_C.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_D.start();
while (thread_D.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
rcd.notifyThread();
thread_D.join();
rcc.notifyThread();
thread_C.join();
rcb.notifyThread();
thread_B.join();
rca.notifyThread();
}
}
And here is the output:
Thread A started
Thread B started
Thread C started
Thread D started
Thread D stopped
Thread C stopped
Thread B stopped
Thread A stopped