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

求高手:看看简单代码的问题
Java code

import java.util.concurrent.TimeUnit;  
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock; 
import java.util.concurrent.locks.Condition; 

class B
{
        Lock lock=new ReentrantLock();
        Condition con=lock.newCondition();
        void f()
        {
                lock.lock();
                System.out.print(Thread.currentThread().getName());
                System.out.println(">>I'm running");
                try { con.await(); }
                catch(InterruptedException ex)
                {
                        System.out.print(Thread.currentThread().getName());
                        System.out.println(">>I'm interrupted!");
                }
                System.out.print(Thread.currentThread().getName()); 
                System.out.println(">>exit!");
        }
}

class A extends Thread
{
        B b;
        A(B b){this.b=b;}
        public void run()
        {
               b.f();
        }
}

public class Test 
{  
    public static void main(String[] args)
    {
            B b=new B();  
            A a=new A(b);
            a.start();
            A aa=new A(b);
            aa.start();
            try{Thread.sleep(1000);}
            catch(InterruptedException ex){/*Deal with it!*/}
            a.interrupt();
            aa.interrupt();
    }  
}  
 


为什么a或aa线程其中有一个不能中断?
想不通问题出在哪儿,求高手!!
API docs:
The lock associated with this Condition is atomically released and the current thread becomes disabled for thread scheduling purposes and lies dormant until one of four things happens:

  Some other thread invokes the signal() method for this Condition and the current thread happens to be chosen as the thread to be awakened; or
  Some other thread invokes the signalAll() method for this Condition; or
  Some other thread interrupts the current thread, and interruption of thread suspension is supported; or
  A "spurious wakeup" occurs. 

In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock.

If the current thread:

  has its interrupted status set on entry to this method; or
  is interrupted while waiting and interruption of thread suspension is supported, 

then InterruptedException is thrown and the current thread's interrupted status is cleared. It is not specified, in the first case, whether or not the test for interruption occurs before the lock is released. 

最后一句话(红色高亮)不是很理解,意思是不是如果在进入await方法时已经设置了中断状态,该方法是否抛出异常与实现有关。。。

------解决方案--------------------
个人浅见:

"In all cases, before this method can return the current thread must re-acquire the lock associated with this condition. When the thread returns it is guaranteed to hold this lock."
查jdk 1.6中文解释:
“在所有情况下,在此方法可以返回当前线程之前,都必须重新获取与此条件有关的锁。在线程返回时,可以保证它保持此锁。 ”

程序在执行a.interrupt();后,a线程从等待状态返回,(因为这是con上的锁是空闲的,a线程持有该锁)。而程序中没有释放,(程序没有lock.unlock()),所以锁就一直被线程a占用着了。

而当执行aa.interrupt()时,线程aa因为无法得到con锁,所以不能从“等待”中返回。这就是为什么aa不能中断的原因。

可以在类B的f()中加上释放锁的语句,aa就可以正常中断了。
Java code

        void f()
        {
                lock.lock();
                System.out.print(Thread.currentThread().getName());
                System.out.println(">>I'm running");
                try {con.await(); }
                catch(InterruptedException ex)
                {
                        System.out.print(Thread.currentThread().getName());
                        System.out.println(">>I'm interrupted!");
                }
        finally
        {
            lock.unlock();        //释放锁.
        }
        }