使用Java中的wait方法

1. 简介

当多个线程需要协同工作时,我们需要使用Java中的wait()方法来实现线程之间的同步。该方法会使线程暂停执行并释放占用的锁,直到其他线程调用notify()或notifyAll()方法来通知它恢复执行。

2. wait()方法的使用

1. wait()方法的语法

    public final native void wait(long timeout) throws InterruptedException; 
    public final void wait(long timeout, int nanos) throws InterruptedException;
    public final void wait() throws InterruptedException;

wait()方法有三个重载形式:

  • wait(long timeout):使当前线程等待指定的毫秒数,或直到被通知或中断。
  • wait(long timeout, int nanos):与wait(long timeout)相似,但增加了纳秒级别的精度。
  • wait():使当前线程一直等待,直到被通知或中断。

2. wait()方法的原理

当线程调用wait()方法时,它会释放掉占有的锁,并让自己进入等待状态,直到其他线程调用了notify()或notifyAll()方法来通知它。

调用wait()方法的线程必须拥有该对象的锁。如果没有,则会抛出IllegalMonitorStateException异常。

一旦线程被通知,它会重新尝试获取锁,并继续执行。

3. wait()方法的应用场景

wait()方法通常用于实现线程之间的同步。下面是一些常见的wait()方法的应用场景:

  • 生产者和消费者模式:使用wait()和notify()方法来协调生产者和消费者线程的工作。当队列为空时,消费者线程会调用wait()方法等待生产者放入数据;而当队列已满时,生产者线程会调用wait()方法等待消费者取走数据。
  • 多线程协作:当多个线程需要互相协作时,可以使用wait()和notify()方法来实现线程之间的通信。

3. 示例代码

1. 生产者与消费者

class Producer extends Thread {
    Queue queue;

    Producer(Queue queue) {
        this.queue = queue;
    }

    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.size() >= 10) {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("生产者生产数据: " + queue.size());
                queue.offer(1);
                queue.notifyAll();
            }
        }
    }
}

class Consumer extends Thread {
    Queue queue;

    Consumer(Queue queue) {
        this.queue = queue;
    }

    public void run() {
        while (true) {
            synchronized (queue) {
                while (queue.isEmpty()) {
                    try {
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("消费者消费数据: " + queue.size());
                queue.poll();
                queue.notifyAll();
            }
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Queue queue = new LinkedList();
        Thread producer = new Producer(queue);
        Thread consumer = new Consumer(queue);
        producer.start();
        consumer.start();
    }
}

2. 多线程协作

class Worker extends Thread {
    private int id;
    private Object prev;
    private Object cur;

    Worker(int id, Object prev, Object cur) {
        this.id = id;
        this.prev = prev;
        this.cur = cur;
    }

    public void run() {
        while (true) {
            synchronized (prev) {
                synchronized (cur) {
                    System.out.println("Worker " + id + " is working.");
                    cur.notifyAll();
                }
                try {
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

public class Main {
    private static final int n = 5;

    public static void main(String[] args) {
        Object[] objects = new Object[n];
        for (int i = 0; i < n; i++) {
            objects[i] = new Object();
        }
        Thread[] threads = new Thread[n];
        for (int i = 0; i < n - 1; i++) {
            threads[i] = new Worker(i, objects[i], objects[i + 1]);
        }
        threads[n - 1] = new Worker(n - 1, objects[n - 1], objects[0]);
        for (Thread t : threads) {
            t.start();
        }
    }
}

4. 总结

本文介绍了Java中的wait()方法,包括其语法、原理和应用场景。我们通过两个示例代码来演示了wait()方法的应用,一个是生产者和消费者模式,一个是多线程协作场景。wait()方法是实现线程之间同步通信的重要工具,我们在实际开发中需要充分理解其原理和应用场景,并适当运用它来提高应用程序的性能和稳定性。

原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/287145.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
小蓝小蓝
上一篇 2024-12-23 13:06
下一篇 2024-12-23 13:06

相关推荐

  • Java JsonPath 效率优化指南

    本篇文章将深入探讨Java JsonPath的效率问题,并提供一些优化方案。 一、JsonPath 简介 JsonPath是一个可用于从JSON数据中获取信息的库。它提供了一种DS…

    编程 2025-04-29
  • java client.getacsresponse 编译报错解决方法

    java client.getacsresponse 编译报错是Java编程过程中常见的错误,常见的原因是代码的语法错误、类库依赖问题和编译环境的配置问题。下面将从多个方面进行分析…

    编程 2025-04-29
  • Java腾讯云音视频对接

    本文旨在从多个方面详细阐述Java腾讯云音视频对接,提供完整的代码示例。 一、腾讯云音视频介绍 腾讯云音视频服务(Cloud Tencent Real-Time Communica…

    编程 2025-04-29
  • Java Bean加载过程

    Java Bean加载过程涉及到类加载器、反射机制和Java虚拟机的执行过程。在本文中,将从这三个方面详细阐述Java Bean加载的过程。 一、类加载器 类加载器是Java虚拟机…

    编程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介绍

    本文将详细介绍Java Milvus SearchParam withoutFields的相关知识和用法。 一、什么是Java Milvus SearchParam without…

    编程 2025-04-29
  • 解决.net 6.0运行闪退的方法

    如果你正在使用.net 6.0开发应用程序,可能会遇到程序闪退的情况。这篇文章将从多个方面为你解决这个问题。 一、代码问题 代码问题是导致.net 6.0程序闪退的主要原因之一。首…

    编程 2025-04-29
  • ArcGIS更改标注位置为中心的方法

    本篇文章将从多个方面详细阐述如何在ArcGIS中更改标注位置为中心。让我们一步步来看。 一、禁止标注智能调整 在ArcMap中设置标注智能调整可以自动将标注位置调整到最佳显示位置。…

    编程 2025-04-29
  • Python创建分配内存的方法

    在python中,我们常常需要创建并分配内存来存储数据。不同的类型和数据结构可能需要不同的方法来分配内存。本文将从多个方面介绍Python创建分配内存的方法,包括列表、元组、字典、…

    编程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一个类的构造函数,在创建对象时被调用。在本篇文章中,我们将从多个方面详细讨论init方法的作用,使用方法以及注意点。 一、定义init方法 在Pyth…

    编程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java语言中的一个版本,于2014年3月18日发布。本文将从多个方面对Java 8中某一周的周一进行详细的阐述。 一、数组处理 Java 8新特性之一是Stream…

    编程 2025-04-29

发表回复

登录后才能评论