下面有4个测试方法,方法1和4可以正常停止,但是方法2/3无法结束。package com.summary;import java.util.concurrent.locks.LockSupport;public class LockSupportParkUnpark implements Runnable {
    public static void main(String[] args) throws Exception {
//        main1();
        main2();
//        main3();
//        main4();
    }    public static void main1() {        LockSupport.unpark(Thread.currentThread());
        System.out.println("c");
        LockSupport.park();
        System.out.println("d");
    }    public static void main2() throws Exception {        System.out.println("a");
        LockSupport.park();
        System.out.println("b");
        Thread.sleep(2000);
        LockSupport.unpark(Thread.currentThread());//无法结束
        System.out.println("c");
    }    public static void main3() throws Exception {        System.out.println("a");
        LockSupport.park();
        System.out.println("b");
        Thread.sleep(2000);
        Thread.currentThread().interrupt();//无法结束
        System.out.println("c");
    }    public static void main4() throws Exception {        Thread t = new Thread(new LockSupportParkUnpark());
        t.start();
        Thread.sleep(2000);
        System.out.println("c");
        t.interrupt();
    }    @Override
    public void run() {
        System.out.println("a");
        LockSupport.park();
        System.out.println("b");
    }
}运行方法2时的线程dump信息

解决方案 »

  1.   

    run 中也有LockSupport.park();
    你main2中的park就会阻塞
      

  2.   

    首先你虽然实现了Runnable接口  但是你没有启动线程  所以你的run方法是没有执行的 所以说你这个程序只有一条线程
    在仔细看看你的方法当你执行到 System.out.println("a");的时候,就说明你的当前线程是有状态的(就是有锁存在或者说运行的许可)
    然后你调用LockSupport.park();再去获得锁(许可)就会出现无法获得锁(许可)因为你当前的线程是有锁的。所以就会造成死锁,所以下边就没办法运行下去。正确的调用方法就是先释放锁(许可),也就是说先调用 LockSupport.unpark(Thread.currentThread());//无法结束在调用LockSupport.park();就可以了
    补充一下:LockSupport.park();这个方法只有在当前线程无状态下才能正确的执行,否则就会造成竞争,出现死锁
      

  3.   

    1.我知道该什么时候用unpark了。好像书上是这么说的。
    2.但是main4方法中,是先运行线程,然后park的。当前新启的线程处于运行中,但是还能调用park。这个与上面违背。
    3.死锁的说法不准确,如果是死锁,线程dump文件是不是应该会明说有死锁,这里是不是类似于“不可重入”锁的意思。
      

  4.   

    难道不是因为执行park方法后,当前线程就阻塞了,没办法执行unpark方法了吗?
      

  5.   


    package com.summary;import java.util.concurrent.locks.LockSupport;public class LockSupportParkUnpark implements Runnable {    Thread t = Thread.currentThread()
        public static void main(String args) throws Exception {
    //        main1();
           // 用另一个线程去解锁
           new LockSupportParkUnpark().start()

            main2();
    //        main3();
    //        main4();
        }    public static void main1() {        LockSupport.unpark(Thread.currentThread());
            System.out.println("c");
            LockSupport.park();
            System.out.println("d");
        }    public static void main2() throws Exception {        System.out.println("a");
            LockSupport.park();
            System.out.println("b");
            Thread.sleep(2000);
            LockSupport.unpark(Thread.currentThread());//无法结束
            System.out.println("c");
        }    public static void main3() throws Exception {        System.out.println("a");
            LockSupport.park();
            System.out.println("b");
            Thread.sleep(2000);
            Thread.currentThread().interrupt();//无法结束
            System.out.println("c");
        }    public static void main4() throws Exception {        Thread t = new Thread(new LockSupportParkUnpark());
            t.start();
            Thread.sleep(2000);
            System.out.println("c");
            t.interrupt();
        }    @Override
        public void run() {
            System.out.println("a");
            LockSupport.unpark(t)
            //LockSupport.park();
            System.out.println("b");
        }
    }