LockSupport先park再unpark为啥不能停止

时间:2023-02-14 20:09:55
下面有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信息
LockSupport先park再unpark为啥不能停止

4 个解决方案

#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 楼 oyljerry 的回复:
run 中也有LockSupport.park();
你main2中的park就会阻塞

他都没有启用线程啊。

#4


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

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

#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 楼 oyljerry 的回复:
run 中也有LockSupport.park();
你main2中的park就会阻塞

他都没有启用线程啊。

#4


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

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