线程阻塞工具类:LockSupport

2023-12-22 22:45:06
public class LockSupportDemo {
    public static Object u = new Object();
    static ChangeObjectThread t1 = new ChangeObjectThread("t1");
    static ChangeObjectThread t2 = new ChangeObjectThread("t2");

    public static class ChangeObjectThread extends Thread{
        public ChangeObjectThread(String name){
            super.setName(name);
        }
        @Override
        public void run(){
            synchronized (u){
                System.out.println("in "+getName());
                LockSupport.park();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        t1.start();
        Thread.sleep(100);
        t2.start();
        LockSupport.unpark(t1);
        LockSupport.unpark(t2);
        t1.join();
        t2.join();
    }
}

这里只是将原来的suspend()方法和resume()方法用
park()方法和unpark()方法做了替换。当然,我们依然
无法保证unpark()方法发生在park()方法之后。
但是执行这段代码,你会发现,它自始至终都可以正常地结束。
不会因为park()方法而导致线程永久挂起。

这是因为LockSupport类使用类似信号量的机制。它为每一个线程准备了一个许可,
如果许可可用,那么park()方法会立即返回,并且消费这个许可(也就是将许可变不可用),
如果许可不可用,就会阻塞,而unpark()方法则使得一个许可变为可用(但是和信号量不同的是,许可不能累加
,你不可能拥有超过一个许可,它永远只有一个)。
这个特点使得,即使unpark()方法操作发生在park()方法之前,
它也可用使下一次的park()方法操作立即返回。也就是上述代码可顺利结束的主要原因。


调用 unpark 给线程一个通行证: 当线程调用了 unpark,它获得了一个许可(通行证)。这个许可有两个作用:

如果线程在调用 park 之前,那么调用 park 时会立即返回,不会阻塞。
如果线程还没有调用 park,那么这个许可就留着,等待线程下一次调用 park 时使用。
两种情况下的作用:

情况一:线程调用了 park: 如果线程在调用 park 之前已经被赋予了许可,那么 park 会立即返回,不会阻塞。
情况二:线程没有调用 park: 如果线程还没有调用 park,但是已经调用了 unpark,那么这个许可就会等待线程下一次调用 park 时使用。当线程下一次调用 park 时,它会消耗这个许可,使得 park 立即返回,不会阻塞。
这种机制的关键点在于,即使 unpark 发生在 park 之前,许可的存在确保了线程在调用 park 时能够顺利通过,不会阻塞。
这使得线程控制更加灵活和可靠。

文章来源:https://blog.csdn.net/wcg_jishuo/article/details/135142186
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。