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#异步多线程使用中的常见问题

    关于“详解C#异步多线程使用中的常见问题”的完整攻略,我准备了以下内容: 详解C#异步多线程使用中的常见问题 1. 什么是异步多线程 异步多线程是指在程序执行期间,同时启动多个线程,并让这些线程在不同的时间段执行任务。异步多线程可以提高程序的性能和效率,尤其是对于一些需要大量计算或等待IO操作完成的任务。 2. 常见问题 2.1. 数据竞争 在异步多线程中,…

    多线程 2023年5月17日
    00
  • Java高并发系统限流算法的实现

    Java高并发系统限流算法的实现攻略 什么是限流算法 限流算法是指限制一个系统的并发数或者流量的算法,一旦超出限制就拒绝服务或者延迟处理。 为什么需要限流算法 在高并发系统中,如果没有限流算法来限制流量或者并发数,就会容易出现系统崩溃或瘫痪的情况。 限流算法分类 固定时间窗口算法 滑动时间窗口算法 漏桶算法 令牌桶算法 固定时间窗口限流算法 固定时间窗口限流…

    多线程 2023年5月16日
    00
  • Java多线程 线程状态原理详解

    Java多线程 线程状态原理详解 介绍 Java中的线程可以并行执行多个代码块,既可提高程序执行效率,又可防止程序因某些阻塞造成“卡死”。 线程状态就是指线程在代码执行期间所处的不同运行状态,进而影响着线程的执行顺序及资源分配。在Java中,线程状态主要由以下5种状态组成: 新建状态(New) 就绪状态(Runnable) 阻塞状态(Blocked) 等待状…

    多线程 2023年5月17日
    00
  • Java线程的基本概念

    Java线程的基本概念 在Java中,一个线程就是一个独立的执行流程,它可以完成特定的任务,以此实现多任务并行处理。Java中的多线程处理提供了一种并发执行应用程序的方式,运行时系统可以同时启动多个线程去执行同一个程序的不同部分,从而提高系统的响应速度和处理能力。 在Java中,线程是由线程对象表示的,线程对象通常在运行时系统中创建,同时,每个线程都有一个与…

    多线程 2023年5月17日
    00
  • Java多线程并发与并行和线程与进程案例

    关于Java多线程并发与并行以及线程与进程的学习攻略,可以按照以下步骤进行: 第一步:了解并发、并行、线程和进程的基本概念 在开始学习Java多线程,首先要了解并发、并行、线程和进程的基本概念。其中: 并发是指同一时间内执行多个任务的能力,比如CPU在多个线程之间快速切换来模拟同时执行多个任务的效果。 并行是指真正地同时执行多个任务,一般需要多个CPU核心来…

    多线程 2023年5月16日
    00
  • Java面试必备之JMM高并发编程详解

    Java面试必备之JMM高并发编程详解攻略 一、JMM是什么? Java内存模型(Java Memory Model,JMM)是Java虚拟机规范中定义的一种计算机内存模型,即Java程序中多线程之间共享变量的访问规则。 Java程序采用多线程技术,为实现高并发效果,需要保证不同线程之间对共享变量的操作可以正确地被其他线程所读取。Java内存模型规定了Jav…

    多线程 2023年5月16日
    00
  • 深入解析Java并发程序中线程的同步与线程锁的使用

    深入解析Java并发程序中线程的同步与线程锁的使用 在Java并发程序中,线程的同步和线程锁是必不可少的。线程的同步是指多个线程协同工作,按一定的顺序执行,而线程锁则是保证多个线程访问共享资源时数据的正确性和一致性。 线程同步 Java中线程同步的主要方式有以下两种: 1. synchronized关键字 synchronized关键字可以修饰方法和代码块,…

    多线程 2023年5月16日
    00
  • java并发编程_线程池的使用方法(详解)

    Java并发编程:线程池的使用方法(详解) 什么是线程池? 线程池是一种线程管理的机制,可以避免频繁创建和销毁线程所带来的开销。通过提前创建一定数量的线程并将它们组织成池,其他需要执行任务的线程可以从池中获取空闲的线程来执行任务。 线程池的优势 使用线程池的优势主要在以下几方面:1. 重用线程,减少线程创建和销毁所带来的开销。2. 更好的管理线程,统一分配、…

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