首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Thread.sleep、Object.wait、LockSupport.park 区别2

Thread.sleep、Object.wait、LockSupport.park 区别2

实现原理

LockSupport.park() 的实现原理是通过二元信号量做的阻塞,要注意的是,这个信号量最多只能加到1。我们也可以理解成获取释放许可证的场景。unpark()方法会释放一个许可证,park()方法则是获取许可证,如果当前没有许可证,则进入休眠状态,知道许可证被释放了才被唤醒。无论执行多少次unpark()方法,也最多只会有一个许可证。
和wait的不同

park、unpark方法和wait、notify()方法有一些相似的地方。都是休眠,然后唤醒。但是wait、notify方法有一个不好的地方,就是我们在编程的时候必须能保证wait方法比notify方法先执行。如果notify方法比wait方法晚执行的话,就会导致因wait方法进入休眠的线程接收不到唤醒通知的问题。而park、unpark则不会有这个问题,我们可以先调用unpark方法释放一个许可证,这样后面线程调用park方法时,发现已经许可证了,就可以直接获取许可证而不用进入休眠状态了。

另外,和wait方法不同,执行park进入休眠后并不会释放持有的锁。
对中断的处理

park方法不会抛出InterruptedException,但是它也会响应中断。当外部线程对阻塞线程调用interrupt方法时,park阻塞的线程也会立刻返回。

    Thread parkThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("park begin");
     
                    //等待获取许可
                    LockSupport.park();
                    //输出thread over.true
                    System.out.println("thread over." + Thread.currentThread().isInterrupted());
     
                }
            });
            parkThread.start();
     
            Thread.sleep(2000);
            // 中断线程
            parkThread.interrupt();
     
            System.out.println("main over");

上面的demo最终会输出

    park begin
    main over
    thread over.true

说明因park进入休眠的线程收到中断通知后也会立刻返回,并且可以手动通过Thread.currentThread().isInterrupted()获取到中断位。
返回列表