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

yizhihongxing

下面我将为你详细讲解“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日

相关文章

  • 带你快速搞定java多线程(5)

    当我们编写Java程序时,有时需要同时执行多个任务。这时,Java多线程就可以发挥它的作用。在前面的四篇文章中,我们已经了解了Java多线程的基础知识,如何创建和启动线程,如何控制线程的状态等等。在本文中,我们将进一步讨论Java多线程的高级知识,包括线程锁、线程池和线程间的通讯。 线程锁 在多线程环境下,如果多个线程同时修改同一个共享资源,就会发生冲突,造…

    多线程 2023年5月17日
    00
  • C#多线程Thread使用示例详解

    下面我将详细讲解“C#多线程Thread使用示例详解”的完整攻略。 C#多线程Thread使用示例详解 什么是多线程? 在计算机里,线程是一个可执行的代码片段。我们可以将线程视为一堆计算机程序指令。一个程序可以同时运行多个线程。多线程技术可以让计算机同时处理多项任务,从而更加高效。 如何使用多线程? 在C#中,可以使用Thread类来实现多线程技术。具体使用…

    多线程 2023年5月17日
    00
  • Java并发系列之CyclicBarrier源码分析

    首先我要解释一下什么是CyclicBarrier。CyclicBarrier是一种在多线程中实现控制并发的同步工具,也可以看作是一种倒计数器。它的作用是允许一组线程在某个时刻全部到达一个屏障点,然后它们可以相互等待,直到所有的线程都到达这个屏障点后一起继续执行。我们可以使用Java的CyclicBarrier类来实现这个功能。 下面是这个攻略的详细步骤: 一…

    多线程 2023年5月16日
    00
  • Java线程同步的四种方式详解

    Java线程同步的四种方式详解 在 Java 并发编程中,线程同步是非常重要的一个话题。线程同步是解决多个线程访问共享资源时所导致的数据不一致或者死锁问题的一种机制。本篇攻略将详细讲解 Java 线程同步的四种方式。 1. synchronized 关键字 synchronized 是 Java 官方提供的最基本的一种同步方式。它可以保证同一个时刻只有一个线…

    多线程 2023年5月16日
    00
  • Java编程思想中关于并发的总结

    Java编程思想中关于并发的总结 Java编程思想这本书的第二十一章讲解了关于并发的内容,本文就对其总结一下。 并发基础 Java中的线程数据结构是非常简单的,Java的线程是一种操作系统线程,Java线程维护着自己的堆栈、程序计数器和一套寄存器。 线程的主要状态有五个,分别是新建、就绪、运行、阻塞和死亡。其中“就绪”状态指线程已经准备好获取CPU,并等待C…

    多线程 2023年5月16日
    00
  • 同步多线程(SMT)是什么意思?有什么作用?

    同步多线程(SMT)是指在计算机系统或处理器架构中支持在一个物理处理器核心上同时运行多个执行线程的技术。这是通过将单个物理处理器核心的资源分配给多个线程来实现的,使得每个线程都可以访问并执行指令,从而提高处理器的吞吐量和执行能力。SMT的实质是在物理上使用了多个逻辑CPU,在逻辑CPU之间切换来掩盖处理器中资源的闲置,从而提高了处理能力。 SMT的主要优点是…

    多线程 2023年5月17日
    00
  • Java并发之线程池Executor框架的深入理解

    Java并发之线程池Executor框架的深入理解 什么是Executor框架? Executor框架是Java提供的一种开发并发程序的机制。在Java中,通常我们需要实现多线程的程序来提高程序执行效率,但是如果使用Java中的Thread类直接去开启线程,可能会导致线程执行不可控、线程消耗过多的系统资源等问题。 Executor框架的出现解决了这些问题。它…

    多线程 2023年5月16日
    00
  • Redis高并发问题的解决方法

    Redis高并发问题的解决方法 1. Redis是什么 Redis是一个高性能的内存数据结构存储系统,常用于缓存、分布式锁、消息队列、计数器等场景,因为其迅速的读写速度和多种数据结构的支持而受到广泛的喜爱。 2. Redis高并发问题分析 Redis在进行并发访问时,会存在以下几个问题: 线程安全问题:Redis单线程模型无法支持并发访问,需要使用线程安全的…

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