日期:2014-05-20  浏览次数:20735 次

关于一个线程的基础问题,头大了,郁闷中
这是从网上找的例子
class ThreadA
{
public static void main(String[] args)
{
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (b)
{
try
{
System.out.println("Waiting for b to complete...");
b.wait();
System.out.println("Completed.Now back to main thread");
}
catch (InterruptedException e)
{
}
}
System.out.println("Total is :" + b.total);
}
}

class ThreadB extends Thread
{
  int total;
  public void run()
  {
    synchronized(this)
    {
      System.out.println("ThreadB is running..");
      for (int i=0;i<100;i++ )
      {
        total +=i;
        System.out.println("total is "+total);
      }
      notify();
      System.out.println("ThreadB is finish..");
    }
  }
}

在运行主程序 ThreadA时,下面是大部分的结果
b is start....
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
............(这是中间省略的结果)
ThreadB is finish..
Waiting for b to complete...
Completed.Now back to main thread
Total is :4950

但是多运行几次后,有时候会出现如下结果虽然是小概率
b is start....
ThreadB is running..
total is 0
total is 1
total is 3
............(这是中间省略的结果)
ThreadB is finish..
Waiting for b to complete...
程序就处于一种无限等待状态,除非我手动结束

我现在的问题是,根据每次的输出结果基本上都是ThreadB 能抢到锁,然后去执行,所以我认为
每次都应该是主线程出现无限等待状态才对.但是实际结果是大部分居然能执行完成,那这里的wait方法,还有什么作用?感觉就没起作用,wait不是说,把线程持有的对象锁释放掉吗,然后线程进入对象的等待集合吗?在这里ThreadA中持有b对象的不就是主线程吗?一旦执行到wait方法,主线程不应该挂起吗,他要向继续执行,不得等其他地方执行notify吗,但是现在notify比他先执行了呀,那永远也不会有线程唤醒他了呀,他怎么还会继续执行呢?

请高人指点

------解决方案--------------------
我现在的问题是,根据每次的输出结果基本上都是ThreadB 能抢到锁,然后去执行,所以我认为
每次都应该是主线程出现无限等待状态才对

========================
不是每次都是ThreadB抢到锁啊,你都说基本上是了。还有不要打印那么多,你sleep一下。看的清楚点。

public class ThreadA {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
System.out.println("b is start....");
synchronized (b) {
try {
System.out.println("Waiting for b to complete...");
System.out.println("before wait...");
b.wait();
System.out.println("after wait...");
System.out.println("Completed.Now back to main thread");
} catch (InterruptedException e) {
}
}
System.out.println("Total is :" + b.total);
}
}

class ThreadB extends Thread {
int total;

public void run() {
synchronized (this) {
System.out.println("ThreadB is running..");
for (int i = 0; i < 10; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
total += i;
System.out.println("total is " + total);
}
notify();
System.out.println("ThreadB is finish..");
}
}
}

两种情况:
1、主线程在ThreadB执行到run之前,执行到sync块里面了。那这种情况就是:
b is start....
Waiting for b to complete...
before wait...
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
total is 15
total is 21
total is 28
total is 36
total is 45
ThreadB is finish..
after wait...
Completed.Now back to main thread
Total is :45

1、主线程在ThreadB执行到run之后,执行到sync块里面了,这个就无限等待了。

b is start....
ThreadB is running..
total is 0
total is 1
total is 3
total is 6
total is 10
total is 15
total is 21
total is 28
total is 36
total is 45
ThreadB is finish..
Waiting for b to complete...
before wait...