java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java notify wait线程通信

Java通过notify和wait实现线程间的通信功能

作者:shengjk1

在软件开发中,线程是实现并发执行的重要手段,然而,线程之间的协作与通信却是开发者必须重点考虑的挑战之一,Java作为一种广泛应用于多线程编程的语言,本文将深入探讨Java中通过notify和wait实现线程间通信的机制,需要的朋友可以参考下

一、前言

在软件开发中,线程是实现并发执行的重要手段,然而,线程之间的协作与通信却是开发者必须重点考虑的挑战之一。Java作为一种广泛应用于多线程编程的语言,提供了一套强大而灵活的机制,让不同线程之间能够优雅地交替执行、传递信息,以实现协调合作。

本文将深入探讨Java中通过notifywait实现线程间通信的机制。

二、notify 和 wait

2.1 wait

2.1.1 wait 基本介绍

通过源码我们可以知道 wait 是 object 对象方法,用于实现线程间的等待和通知机制。当一个线程调用wait()方法时,它会释放当前所持有的对象锁,并进入等待状态,直到被其他线程调用相同对象上的notify()notifyAll()方法唤醒。

public final void wait() throws InterruptedException {
    wait(0);
}

2.1.2 wait 注意点

Object o = new Object();
o.wait(); //java.lang.IllegalMonitorStateException
   synchronized (obj) {
          while (<condition does not hold>)
              obj.wait(timeout);
          ... // Perform action appropriate to condition
      }

2.1.3 wait 使用场景

wait()方法是在Java中用于线程间通信和同步的重要方法之一。它通常与synchronized关键字一起使用,用于在多线程中协调线程之间的操作。下面是wait()方法的一些常见使用场景:

2.1.4 wait 的执行原理

2.1.5 wait 使用

2.2 notify

首先我们需要知道 nofity 和 notifyall 基本上是等价的,如没有特别标明,nofity 和 nofityall 是一样的

2.2.1 notify 基本介绍

通过源码我们可以知道 notify 是 object 对象方法。

notify()是线程间通信的一种机制,用于唤醒在当前对象上等待的一个线程。当一个线程调用notify()方法时,它会唤醒正在该对象上等待的单个线程(如果有多个线程在等待,系统无法确定哪个线程会被唤醒,因为选择是随机的)。这个被唤醒的线程将从等待状态变为可运行状态,但并不意味着立即获得对象的锁。

public final native void notify();

当一个线程调用notifyAll()时,它会唤醒在当前对象上等待的所有线程,使它们从等待状态转变为可运行状态。这样,所有等待中的线程都有机会争取获取对象锁,在某个线程获得锁后,它们会竞争执行。

2.2.2 notify 注意点

下面是关于notify()方法的一些重要点:

2.2.3 nofityall

以下是关于notifyAll()方法的详细介绍:

2.2.4 notify 使用场景

notify()的使用场景:

notifyAll()的使用场景:

2.2.5 notify 的执行原理

notify()方法的执行原理:

notifyAll()方法的执行原理:

2.2.6 notify和notifyAll 注意事项和要点:

三、wait/nofity 经典使用方式

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class WaitNotify {
    static boolean flag = true;
    static Object  lock = new Object();

    public static void main(String[] args) {
       Thread waitThread = new Thread(new Wait(), "waitThread");
       waitThread.start();
       try {
          TimeUnit.SECONDS.sleep(1);
       } catch (InterruptedException e) {
          e.printStackTrace();
       }

       new Thread(new Notify(), "notifyThread").start();


    }

//wait
    static class Wait implements Runnable {
       public void run() {
          synchronized (lock) {
             while (flag) {
                try {
                   System.out.println(Thread.currentThread() + " flag is true" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
                   //没有释放资源 wait 等待
                   lock.wait();
                } catch (InterruptedException e) {
                }
             }
             System.out.println(Thread.currentThread() + " flag is false" + new SimpleDateFormat("HH:mm:ss").format(new Date()));

          }
       }
    }

    static class Notify implements Runnable {
       public void run() {
          synchronized (lock) {
             while (flag) {
                System.out.println(Thread.currentThread() + "hold lock  notify" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
                //资源准备
                好了,nofity
                lock.notifyAll();
                flag = false;
                try {
                   TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                   e.printStackTrace();
                }

             }
          }
          synchronized (lock) {
             System.out.println(Thread.currentThread() + "hold lock again. notify" + new SimpleDateFormat("HH:mm:ss").format(new Date()));
             try {
                TimeUnit.SECONDS.sleep(5);
             } catch (InterruptedException e) {
                e.printStackTrace();
             }

          }
       }
    }
}

这是最经典的等待/通知的范式:但资源没有准备好时,wait 等待,当资源准备好了,notify 通知。

四、总结

文章详细讲解了Java中waitnotify方法的使用方法和注意事项,通过这些方法实现线程间的协调与通信,并列举了常见的使用场景,如协调多个线程操作、实现生产者-消费者模型等。此外,文章还强调了waitnotify方法必须在同步块中调用,以确保线程安全。

以上就是Java通过notify和wait实现线程间的通信功能的详细内容,更多关于Java notify wait线程通信的资料请关注脚本之家其它相关文章!

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