Java多线程阻塞与唤醒代码示例

下面是Java多线程阻塞与唤醒代码示例的完整攻略。

前置知识

在开始讲解Java多线程阻塞与唤醒代码示例之前,需要掌握以下知识点:

  • 多线程的概念与基本操作,如创建线程、线程同步等;
  • 线程阻塞与唤醒的概念与使用方法,如wait()、notify()、notifyAll()等;
  • 线程状态的概念与使用,如Thread.State等。

示例一:生产者与消费者问题

生产者与消费者问题是一个非常经典的多线程问题,常用于考察多线程的基本操作、线程同步、线程阻塞与唤醒等知识点。下面给出一个生产者与消费者问题的代码示例:

public class ProducerConsumerExample {
    private static final int BUFFER_SIZE = 10;
    private static Queue<Integer> buffer = new LinkedList<>();

    public static void main(String[] args) {
        Thread producer = new ProducerThread();
        Thread consumer = new ConsumerThread();
        producer.start();
        consumer.start();
    }

    private static class ProducerThread extends Thread {
        @Override
        public void run() {
            int i = 0;
            while (true) {
                synchronized (buffer) {
                    if (buffer.size() < BUFFER_SIZE) {
                        buffer.offer(i++);
                        System.out.println("ProducerThread: Produced " + i);
                        buffer.notify();
                    } else {
                        try {
                            buffer.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    private static class ConsumerThread extends Thread {
        @Override
        public void run() {
            while (true) {
                synchronized (buffer) {
                    if (!buffer.isEmpty()) {
                        int value = buffer.poll();
                        System.out.println("ConsumerThread: Consumed " + value);
                        buffer.notify();
                    } else {
                        try {
                            buffer.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }
}

上述代码实现了一个生产者与消费者协作的模型,生产者线程向一个固定长度的缓冲区中生产数字,消费者线程从缓冲区中取出数字并打印。其中,ProducerThread和ConsumerThread分别是生产者和消费者的线程类,buffer是一个缓冲区队列,BUFFER_SIZE是缓冲区队列的容量。线程协作的具体实现如下:

  1. 在生产者线程中,判断缓冲区队列是否已经满了,如果没有就生产一个数字插入队列,并调用buffer.notify()方法唤醒等待的消费者线程,否则就调用buffer.wait()方法进入等待状态。
  2. 在消费者线程中,判断缓冲区队列是否为空,如果不为空就取出一个数字打印,并调用buffer.notify()方法唤醒等待的生产者线程,否则就调用buffer.wait()方法进入等待状态。

通过上述代码示例,我们可以了解到Java多线程阻塞与唤醒的具体使用方法,并且实现了经典的生产者与消费者问题。

示例二:线程池的阻塞队列

线程池是一个非常常用的多线程技术,实现线程池需要使用到阻塞队列。下面给出一个线程池的阻塞队列的代码示例:

public class ThreadPoolWithBlockingQueueExample {
    private static final int POOL_SIZE = 2;
    private static final int TASK_NUM = 5;
    private static final int QUEUE_SIZE = 3;
    private static ExecutorService threadPool = new ThreadPoolExecutor(
            POOL_SIZE,
            POOL_SIZE,
            0L,
            TimeUnit.MILLISECONDS,
            new ArrayBlockingQueue<>(QUEUE_SIZE),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    public static void main(String[] args) throws InterruptedException {
        for (int i = 0; i < TASK_NUM; i++) {
            int taskId = i + 1;
            threadPool.execute(() -> {
                System.out.println("Task " + taskId + " is running on " + Thread.currentThread().getName());
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        threadPool.shutdown();
        while (!threadPool.awaitTermination(100L, TimeUnit.MILLISECONDS)) {
            System.out.println("Wait for thread pool termination");
        }
        System.out.println("Thread pool is terminated");
    }
}

上述代码实现了一个线程池的阻塞队列模型,其中,ThreadPoolWithBlockingQueueExample是程序入口类,POOL_SIZE是线程池的核心线程数,TASK_NUM是任务的数量,QUEUE_SIZE是阻塞队列的大小,threadPool是线程池对象。线程协作的具体实现如下:

  1. 在main函数中,使用for循环向线程池中提交任务,每个任务都会打印一句话,并且线程会睡眠1s模拟任务执行时间。
  2. 在提交任务之后,调用threadPool.shutdown()方法关闭线程池,并且使用threadPool.awaitTermination()方法等待线程池中的线程执行完毕。
  3. 在等待线程池中的线程执行完毕的过程中,程序会不断打印"Wait for thread pool termination",直到线程池中的线程执行完毕,程序才会打印"Thread pool is terminated"。

通过上述代码示例,我们可以了解到线程池的阻塞队列是如何阻塞和唤醒线程的,以及如何正确地关闭线程池。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程阻塞与唤醒代码示例 - Python技术站

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

相关文章

  • 什么是类加载机制?

    以下是关于类加载机制的详细讲解: 什么是类加载机制? 类加载机制是 Java 虚拟机(JVM)在运行时将类的字节码加载到内存,并转换 Java 类的过程。加载机制是 Java 语言的核心机制之一,它负责将类的字节码加载到内存中,并在运行时动态和初始化类。 类加载机制包括以下三个步骤: 加载:将类的字节码加载到内存中。 链接将类的二进制数据合并到 Java 运…

    Java 2023年5月12日
    00
  • 小伙熬夜用Java重现经典超级马里奥代码实例

    下面我来详细讲解“小伙熬夜用Java重现经典超级马里奥代码实例”的完整攻略。 1. 准备工作 首先,我们需要准备一些工具和环境。 1.1 编程语言本次重现经典超级马里奥代码的编程语言为Java,所以我们需要先安装JDK并配置好环境变量。 1.2 IDEIDE是开发Java程序必不可少的,选择一款自己喜欢的IDE,比如Eclipse或者IntelliJ IDE…

    Java 2023年5月23日
    00
  • Java实现从数据库导出大量数据记录并保存到文件的方法

    Java实现从数据库导出大量数据记录并保存到文件的方法,大概分为以下几步: 首先,需要连接数据库,并且执行查询操作获取数据结果集。 // 加载数据库驱动 Class.forName("com.mysql.jdbc.Driver"); // 创建数据库连接 Connection con = DriverManager.getConnecti…

    Java 2023年5月19日
    00
  • SpringBoot整合MybatisSQL过滤@Intercepts的实现

    下面我将为您详细讲解Spring Boot整合Mybatis SQL过滤@Intercepts的实现的完整攻略。 一、介绍 在使用Mybatis框架时,可能会出现需要对传入的SQL参数进行过滤的需求,如防止SQL注入等。此时可以使用Mybatis提供的@Intercepts注解实现SQL过滤的操作,本文主要介绍如何将@Intercepts与Spring Bo…

    Java 2023年5月20日
    00
  • Java构造函数通透理解篇

    Java构造函数通透理解篇 什么是构造函数 构造函数是一种特殊的函数,用于在创建对象时进行初始化操作。在Java语言中,构造函数名称必须与类名称完全一致,且没有返回值类型,因为构造函数的返回值类型就是类本身。 构造函数的作用 构造函数的主要作用是用于在创建对象时进行初始化操作,它会被自动调用,并设置类的初始状态。在构造函数中,可以进行对对象的属性进行初始化,…

    Java 2023年5月26日
    00
  • Java CAS机制详解

    Java CAS机制详解 什么是CAS机制 CAS(Compare And Swap),即比较并替换,是一种并发控制方式。它的思想是:当多个线程尝试同时更新某一个内存地址时,只有其中一个线程能更新成功,而其余的线程都需要等待。这种方式在并发编程中是很常见的。 CAS机制是通过硬件保证操作的原子性,来避免线程安全问题。 CAS操作的原理 CAS机制需要涉及到三…

    Java 2023年5月26日
    00
  • JavaWeb项目中classpath路径详解

    JavaWeb项目中classpath路径详解 在JavaWeb项目中,classpath路径是非常重要的,它对项目中的各种资源进行了管理和访问。本篇文章将详细讲解JavaWeb项目中classpath路径的相关知识和使用方法。 什么是classpath路径? classpath(类路径)指明了Java程序运行时候的类加载路径,它是JVM在寻找类文件时候的默…

    Java 2023年6月16日
    00
  • java MyBatis拦截器Inteceptor详细介绍

    Java MyBatis拦截器Inteceptor详细介绍 什么是MyBatis拦截器Inteceptor MyBatis拦截器Inteceptor是MyBatis中的一个重要组件,使用拦截器可以实现对MyBatis的许多事务进行拦截和控制,比如SQL执行、查询结果处理等等。MyBatis拦截器Inteceptor主要由两部分组成:拦截器接口和拦截对象。 如…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部