This is not the case.Before i start explaining remember "A single thread may hold a lock more than once."
Here is what is actually happening.
When you call b.start() although you have started the new thread b, main is still running and it enters the synchronized block and it aquires the lock first, which causes your run function to hold its activity. Hence it doesnt enter the synch block in the run function. Then the b.wait() is encountered. At this the synch block leaves the monitor and b again takes the monitor this time for the run function which was suspended. it performs all the activity then it sends notify. we then return to statement at b.wait() it recieves the notification and becomes active. it has nothing to perform here ( as no function except run). Simultaneously the main thread is also working. both the threads terminate. The order might differ.
Hope you understand.
In order to achieve what you want i.e to hang the application you must make the main thread to sleep for a short duration before it enters the synch block in main. Then the output will be the one that you desire. something like this.
class ThreadA
{
public static void main(
String[] args) throws InterruptedException
{
ThreadB b = new ThreadB();
b.start();
Thread.sleep(1000);
synchronized(b)
{
try
{
b.wait();}
catch(InterruptedException ie)
{
}
}
}
}
class ThreadB extends Thread
{
int total;
public void run()
{
synchronized(this)
{
for(int i = 0; i< 100; i++)
{
total += 1;
}
notify();
}
}
}