Java多线程wait()和notify()方法详细图解

下面我将为你详细讲解“Java多线程wait()和notify()方法详细图解”的完整攻略。

什么是wait()和notify()方法?

Java多线程的wait()和notify()方法是多线程协作技术的核心。等待/通知机制的目的就是解决线程间协作的问题,它通常是指一个或多个线程等待另一个线程的通知而处于阻塞状态,然后另一个线程发出通知以唤醒这些等待的线程。

wait()方法和notify()方法就是一对典型的等待/通知机制方法,它们都属于Object类的方法,而且只能在同步块或同步方法中使用。在调用这两个方法时,必须首先获得对象的锁,然后才能调用wait()方法释放锁并进入等待状态,调用notify()方法通知等待状态的线程而使其重新获得锁并进入就绪状态。下面是wait()方法和notify()方法的详细说明:

  • wait()方法

    wait()方法用于让当前线程处于等待状态,直到其他线程调用notify()或notifyAll()方法来唤醒它。wait()方法必须在synchronized块或synchronized方法中调用,否则会抛出IllegalMonitorStateException异常。

  • notify()方法

    notify()方法用于唤醒在当前对象上等待的一个线程,如果有多个线程在等待,只会唤醒其中一个线程,并且是系统随机选择的。如果需要唤醒全部等待的线程,则需要使用notifyAll()方法。notify()方法也必须在synchronized块或synchronized方法中进行调用,否则会抛出IllegalMonitorStateException异常。

wait()和notify()方法的示例

下面我将为你提供两个示例来讲解wait()和notify()方法的使用:

示例一:生产者-消费者模式

在这个示例中,我们将使用生产者-消费者模式来演示wait()和notify()方法的使用。

class Message {

    private String message;
    private boolean isSet;

    public synchronized void put(String message) {
        if (this.isSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.message = message;
        this.isSet = true;
        notify();
    }

    public synchronized String get() {
        if (!this.isSet) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        String message = this.message;
        this.isSet = false;
        notify();
        return message;
    }

}

class Producer implements Runnable {

    private Message message;

    public Producer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            this.message.put("Message-" + i);
        }
    }
}

class Consumer implements Runnable {

    private Message message;

    public Consumer(Message message) {
        this.message = message;
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println("Received Message: " + this.message.get());
        }
    }
}

public class WaitNotifyExample {

    public static void main(String[] args) {
        Message message = new Message();

        Thread producerThread = new Thread(new Producer(message));
        Thread consumerThread = new Thread(new Consumer(message));

        producerThread.start();
        consumerThread.start();

        try {
            producerThread.join();
            consumerThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

上述示例中,我们定义了一个Message类来保存消息,并且在Message类中实现了put()方法和get()方法,put方法用于发送消息,get方法用于接收消息,并且在这两个方法中使用了wait()和notify()方法来实现线程间的协作。在程序运行时,我们启动了一个生产者线程和一个消费者线程,并且在main方法中使用join()方法来等待两个线程的结束。

示例二:简单线程池

在这个示例中,我们将使用一个简单的线程池来演示wait()和notify()方法的使用。

class SimpleThreadPool {

    private final BlockingQueue<Runnable> taskQueue;
    private final List<WorkerThread> workerThreads;
    private volatile boolean isShutdown;

    public SimpleThreadPool(int poolSize, int maxTasks) {
        this.taskQueue = new ArrayBlockingQueue<>(maxTasks);
        this.workerThreads = new ArrayList<>(poolSize);
        this.isShutdown = false;

        for (int i = 0; i < poolSize; i++) {
            WorkerThread workerThread = new WorkerThread("Thread-" + i, this.taskQueue, this);
            this.workerThreads.add(workerThread);
            workerThread.start();
        }
    }

    public void submit(Runnable task) throws InterruptedException {
        if (this.isShutdown) {
            throw new IllegalStateException("Thread pool is shut down.");
        }
        this.taskQueue.put(task);
    }

    public void shutdown() {
        this.isShutdown = true;
        this.workerThreads.forEach(WorkerThread::shutdown);
    }

}

class WorkerThread extends Thread {

    private final BlockingQueue<Runnable> taskQueue;
    private final SimpleThreadPool threadPool;
    private volatile boolean isShutdown;

    public WorkerThread(String name, BlockingQueue<Runnable> taskQueue, SimpleThreadPool threadPool) {
        super(name);
        this.taskQueue = taskQueue;
        this.threadPool = threadPool;
        this.isShutdown = false;
    }

    @Override
    public void run() {
        while (!this.isShutdown || !this.taskQueue.isEmpty()) {
            try {
                Runnable task = this.taskQueue.poll(1, TimeUnit.SECONDS);
                if (task != null) {
                    System.out.println(Thread.currentThread().getName() + ": Starting task.");
                    task.run();
                    System.out.println(Thread.currentThread().getName() + ": Task completed.");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void shutdown() {
        this.isShutdown = true;
    }
}

public class WaitNotifyExample {

    public static void main(String[] args) throws InterruptedException {
        SimpleThreadPool threadPool = new SimpleThreadPool(2, 4);

        for (int i = 0; i < 6; i++) {
            threadPool.submit(() -> {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + ": Executing task.");
            });
        }

        Thread.sleep(5000);
        threadPool.shutdown();
    }

}

上述示例中,我们定义了一个SimpleThreadPool类来实现一个简单的线程池,并且使用了wait()和notify()方法来实现线程间的协作。在程序运行时,我们使用一个线程池来提交6个任务,并且在任务执行完毕后关闭线程池。在线程池中,我们启动了两个执行任务的线程,并且使用wait()方法来使线程等待任务队列中有新的任务时,notify()方法来唤醒等待线程继续执行任务。

以上就是对“Java多线程wait()和notify()方法详细图解”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程wait()和notify()方法详细图解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • c#使用多线程的几种方式示例详解

    Markdown格式文本是一种轻量级的标记语言,可以方便地对文本进行排版和格式化,使得文本更具可读性和可维护性。在本文中,我们将详细介绍如何使用Markdown格式文本编写“C#使用多线程的几种方式示例详解”的完整攻略,包含至少两条示例说明。 C#使用多线程的几种方式示例详解 概述 多线程是一种并发执行模型,可以提高程序性能和响应速度。C#是一种支持多线程编…

    多线程 2023年5月17日
    00
  • springboot+websocket实现并发抢红包功能

    一、前言 在现在的Web应用开发中,实时性的需求越来越高,一种常见的技术就是WebSocket。WebSocket是HTML5中新增的协议,可以实现客户端和服务端的全双工通信,而不需要像HTTP那样每次请求后都要断开连接。 Spring Boot是一个基于Spring框架的Web应用开发框架,可以构建独立的、生产级别的Spring应用程序,简化了Spring…

    多线程 2023年5月16日
    00
  • JAVA多线程线程安全性基础

    关于JAVA多线程线程安全性,我给您讲一下我的理解。 什么是线程安全性? 在多线程开发中,往往有多个线程同时访问同一个共享资源,这时候就需要考虑线程安全性问题。当多个线程同时访问某一个对象时,如果不加以协调导致操作结果被破坏,则称为线程不安全。而当多个线程访问某一个对象时,不管运行时环境采用何种调度方式或者这些计算机内核以什么顺序来执行线程,而且在主调代码中…

    多线程 2023年5月17日
    00
  • Java多线程并发编程 Synchronized关键字

    Java多线程并发编程Synchronized关键字 什么是Synchronized关键字? 在Java多线程并发编程中,Synchronized关键字可以用来保证多个线程在访问共享资源时的同步性。它可以实现线程安全的同步操作。 Synchronized关键字的用法 Synchronized关键字可以加在方法和代码块上面。 方法上的Synchronized关…

    多线程 2023年5月16日
    00
  • Golang超全面讲解并发

    Golang超全面讲解并发 简介 本文将介绍Golang并发相关的知识,包括如何使用goroutine和channel等内容。并发编程是Golang的一大特色,也是Golang广泛应用的原因之一。本文可以帮助有一定Golang基础的开发者更好的理解并发编程的概念和实现。 Goroutine Goroutine是Golang并发编程的关键,每个Goroutin…

    多线程 2023年5月16日
    00
  • Java 模拟真正的并发请求详情

    Java模拟真正的并发请求,一般用于性能测试、接口测试等方面,在实际开发过程中也非常有用。下面我们就来详细讲解Java模拟真正的并发请求的攻略。 1. Apache HttpComponents 客户端 使用Apache HttpComponents客户端库来发送HTTP请求。可以使用以下依赖项将其导入Maven项目。 <dependency> …

    多线程 2023年5月16日
    00
  • 实例讲解spring boot 多线程

    下面是详细讲解“实例讲解spring boot 多线程”的完整攻略。 一、什么是多线程 在计算机科学领域,多线程是指程序同时执行多个线程。多线程可以提高程序的并发性,提高CPU的使用率,从而提高程序的运行效率。 二、为什么要使用多线程 通常情况下,当程序的运行需要等待外部事件发生时,我们会使用线程来进行异步处理,保证程序的运行流畅,不会被阻塞。此外,多线程还…

    多线程 2023年5月17日
    00
  • Python并发之多进程的方法实例代码

    关于“Python并发之多进程的方法实例代码”的完整攻略,我可以从以下几个方面进行详细讲解: 1. 什么是多进程? 多进程是一种并发编程的方法,它可以让程序同时执行多个任务。在Python中,可以使用multiprocessing模块来实现多进程编程。每个进程都有自己独立的内存空间,可以并发执行不同的任务,从而提高程序的执行效率。 2. 多进程的方法 使用P…

    多线程 2023年5月16日
    00
合作推广
合作推广
分享本页
返回顶部