首页 > 基础资料 博客日记

java线程通讯之wait与notify

2023-07-26 20:31:31基础资料围观248

Java资料网推荐java线程通讯之wait与notify这篇文章给大家,欢迎收藏Java资料网享受知识的乐趣

概述

wait与notify方法是jdk定义在Object类中的方法,因此所有类实例都可以成为用来实现线程之间通讯的监视器

Object类中方法定义

/**
* 会使调用线程状态变更为WATING状态 并且 会释放锁
*/
public final void wait() throws InterruptedException;
/**
* 会随机唤醒等在当前监视器的1个线程
*/
public final native void notify();
/**
* 唤醒所有等待在当前监视器的线程
*/
public final native void notifyAll();

使用时注意事项

  1. 必须在syncronized代码块内中调用

  2. 注意死锁问题

作用

  1. 让线程处于等待状态

  2. 生产者消费者 实现

线程之间通讯的例子

以下示例实现一个 一问一答的线程通讯

package com.nanxhs.concurrent.thread.message;

/**
 * @author: haibin.tang
 * @date: 2021/1/27
 */
public class Question {
    private int a;
    private int b;

    public Question(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getA() {
        return a;
    }

    public int getB() {
        return b;
    }
}
package com.nanxhs.concurrent.thread.message;

import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

/**
 *  为了测试 Object.wait 与 Object.notify的使用
 * @author: haibin.tang
 * @date: 2021/1/27
 */
public class ChatService {
    /**
     * 监视器锁
     */
    private final Object MONITOR = new Object();
    /**
     * 问题
     */
    private Question question;

    /**
     * 问题线程
     */
    public void a() {
        new Thread(() -> {
            synchronized (MONITOR) {
                while (true) {
                    try {
                        question = new Question((int)(Math.random() * 1000), (int)(Math.random() * 100));
                        System.out.println("问题: " + question.getA() + " + " + question.getB() + " = ?");
                        //随机唤醒其它等待在 MONITOR 监视器的线程
                        MONITOR.notify();
                        //让当前线程等待并且释放锁
                        MONITOR.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

    /**
     * 计算答案的线程
     */
    public void b() {
         new Thread(() -> {
            synchronized (MONITOR) {
                while (true) {
                    if (Objects.isNull(question)) {
                        try {
                            //随机唤醒其它等待在 MONITOR 监视器的线程
                            MONITOR.notify();
                            //让当前线程等待并且释放锁
                            MONITOR.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        //当前线程阻塞1秒
                        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
                        System.out.println("答案: " + (question.getA() + question.getB()));
                        //当前线程阻塞1秒
                        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(1));
                        question = null;
                        //随机唤醒其它等待在 MONITOR 监视器的线程
                        MONITOR.notify();
                        try {
                            //让当前线程等待并且释放锁
                            MONITOR.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }

    public static void main(String[] args) {
        ChatService chatService = new ChatService();
        chatService.a();
        chatService.b();
    }
}

运行结果

问题: 586 + 89 = ?
答案: 675
问题: 733 + 53 = ?
答案: 786
问题: 737 + 21 = ?
答案: 758
问题: 347 + 10 = ?
答案: 357
问题: 991 + 17 = ?
答案: 1008
.....
.....

文章来源:https://www.cnblogs.com/nanxhs/p/16501841.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

上一篇:java AQS分析
下一篇:java 挂起线程

相关文章

本站推荐

标签云