java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java多线程wait、notify和park

Java多线程中的wait、notify和park、unpark的使用详解

作者:小晨想好好学习

这篇文章主要介绍了Java多线程中的wait、notify和park、unpark的使用详解,它们都是线程之间进行协作的手段,都属于 Object 对象的方法,必须获得此对象的锁,才能调用这几个方法,需要的朋友可以参考下

一、wait & notify的使用

1、API介绍

它们都是线程之间进行协作的手段,都属于 Object 对象的方法。

必须获得此对象的锁,才能调用这几个方法 wait() 方法会释放对象的锁,进入 WaitSet 等待区,从而让其他线程就机会获取对象的锁。

无限制等待,直到notify 为止 wait(long n) 有时限的等待, 到 n 毫秒后结束等待,或是被 notify notify 只能随机唤醒一个 WaitSet 中的线程,这时如果有其它线程也在等待,那么就可能唤醒不了正确的线程,称之为【虚假唤醒】

2、demo

@Slf4j(topic = "c.TestCorrectPosture")
public class TestCorrectPostureStep5 {
    static final Object room = new Object();
    static boolean hasCigarette = false;
    static boolean hasTakeout = false;
    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (room) {
                log.debug("有烟没?[{}]", hasCigarette);
                while (!hasCigarette) {
                    log.debug("没烟,先歇会!");
                    try {
                        room.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("有烟没?[{}]", hasCigarette);
                if (hasCigarette) {
                    log.debug("可以开始干活了");
                } else {
                    log.debug("没干成活...");
                }
            }
        }, "小南").start();
        new Thread(() -> {
            synchronized (room) {
                Thread thread = Thread.currentThread();
                log.debug("外卖送到没?[{}]", hasTakeout);
                while (!hasTakeout) {
                    log.debug("没外卖,先歇会!");
                    try {
                        room.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                log.debug("外卖送到没?[{}]", hasTakeout);
                if (hasTakeout) {
                    log.debug("可以开始干活了");
                } else {
                    log.debug("没干成活...");
                }
            }
        }, "小女").start();
        sleep(1);
        new Thread(() -> {
            synchronized (room) {
                hasTakeout = true;
                log.debug("外卖到了噢!");
                room.notifyAll();
            }
        }, "送外卖的").start();
    }
}

在这里插入图片描述

2、多线程模式

模式之保护性暂停 模式之生产者消费者

3、wait和notify的原理

在这里插入图片描述

二、Park & Unpark的使用

1、基本使用

它们是 LockSupport 类中的方法

// 暂停当前线程
LockSupport.park(); 
// 恢复某个线程的运行
LockSupport.unpark(暂停线程对象)

先 park 再 unpark

public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("start...");
            sleep(1);
            log.debug("park...");
            LockSupport.park();
            log.debug("resume...");
        }, "t1");
        t1.start();
        sleep(4);
        log.debug("unpark...");
        LockSupport.unpark(t1);
    }

在这里插入图片描述

先 unpark 再 park

public static void main(String[] args) {
        Thread t1 = new Thread(() -> {
            log.debug("start...");
            sleep(2);
            log.debug("park...");
            LockSupport.park();
            log.debug("resume...");
        }, "t1");
        t1.start();
        sleep(1);
        log.debug("unpark...");
        LockSupport.unpark(t1);
    }

在这里插入图片描述

结论:park和unpark是成对出现,但是是不分先后的

2、特点

与 Object 的 wait & notify 相比

到此这篇关于Java多线程中的wait、notify和park、unpark的使用详解的文章就介绍到这了,更多相关Java多线程wait、notify和park内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文