Java多线程Condition接口原理介绍

yizhihongxing

下面是对于Java多线程Condition接口的原理介绍:

Condition接口是什么?

在Java中,我们可以使用synchronizedwait()notify()notifyAll()等来进行线程同步和通信。而条件对象(Condition)是在Java 5中新增的,它可以更加灵活地控制线程的等待和唤醒,提供了更高级、更安全、更灵活的线程同步方式。

Condition的基本使用

条件对象是与一个锁绑定的,要创建一个条件对象,我们需要先获取锁,然后使用ReentrantLock类的方法newCondition()来创建:

ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();

这样我们就创建了一个条件变量,下一步就可以通过调用conditionawait()方法使得线程进入等待状态,直到调用conditionsignalAll()方法或者signal()方法唤醒线程。

下面是一个简单的示例,两个线程分别执行加和减操作,当结果为零时,主线程输出结果并结束程序。具体的实现过程如下:

public class ConditionDemo {
    private int sum;

    private ReentrantLock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void add() {
        lock.lock();
        try {
            sum++;
            System.out.println(Thread.currentThread().getName() + " add: " + sum);
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void sub() {
        lock.lock();
        try {
            while (sum == 0) {
                condition.await();
            }
            sum--;
            System.out.println(Thread.currentThread().getName() + " sub: " + sum);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ConditionDemo demo = new ConditionDemo();

        Runnable addTask = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    demo.add();
                }
            }
        };

        Runnable subTask = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    demo.sub();
                }
            }
        };

        Thread addThread1 = new Thread(addTask);
        Thread addThread2 = new Thread(addTask);
        Thread subThread = new Thread(subTask);

        addThread1.start();
        addThread2.start();
        subThread.start();

        try {
            addThread1.join();  // 等待线程结束
            addThread2.join();
            subThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("Result: " + demo.sum);
    }
}

上述程序中,使用了一个变量sum来保存加减的结果。在加操作中,我们先获取锁,然后将sum增加1,输出结果,并唤醒所有等待condition的线程。在减操作中,我们先获取锁,然后不断判断sum是否为0,如果为0,则调用conditionawait()方法等待;直到被唤醒后,将sum减1,并输出结果。在主线程中,我们启动两个加操作线程和一个减操作线程,等待所有线程运行结束后,输出结果。

使用Condition实现生产者-消费者模式

生产者-消费者模式是大家比较熟悉的一种应用场景。可以使用Condition来实现,示例如下:

public class ProducerConsumerDemo {

    private LinkedList<Integer> buffer = new LinkedList<Integer>();

    private ReentrantLock lock = new ReentrantLock();
    private Condition notEmpty = lock.newCondition();
    private Condition notFull = lock.newCondition();

    public void produce() {
        lock.lock();
        try {
            while (buffer.size() == 10) {
                notFull.await();
            }
            int value = new Random().nextInt(100);
            buffer.addLast(value);
            System.out.println(Thread.currentThread().getName() + " produce " + value);
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public int consume() {
        lock.lock();
        try {
            while (buffer.size() == 0) {
                notEmpty.await();
            }
            int value = buffer.removeFirst();
            System.out.println(Thread.currentThread().getName() + " consume " + value);
            notFull.signalAll();
            return value;
        } catch (InterruptedException e) {
            e.printStackTrace();
            return -1;
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        ProducerConsumerDemo demo = new ProducerConsumerDemo();

        Runnable produceTask = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    demo.produce();
                }
            }
        };

        Runnable consumeTask = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    demo.consume();
                }
            }
        };

        Thread producer1 = new Thread(produceTask, "producer1");
        Thread producer2 = new Thread(produceTask, "producer2");
        Thread consumer1 = new Thread(consumeTask, "consumer1");
        Thread consumer2 = new Thread(consumeTask, "consumer2");

        producer1.start();
        producer2.start();
        consumer1.start();
        consumer2.start();

        try {
            producer1.join();
            producer2.join();
            consumer1.join();
            consumer2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上述示例中,我们使用了一个LinkedList来存储数据。在生产操作中,如果buffer已经满了,那就调用notFull.await()等待;直到有消费者调用了consume()方法,拿走了一些数据,此时有足够的空间存储新的数据,就可以唤醒正在等待的生产者线程。在消费操作中,如果buffer为空,就调用notEmpty.await()等待;直到有生产者调用了produce()方法,放入了一些数据,此时就可以从buffer中取出数据,唤醒正在等待的消费者线程。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java多线程Condition接口原理介绍 - Python技术站

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

相关文章

  • 关于Hibernate的一些学习心得总结

    关于Hibernate的一些学习心得总结 什么是Hibernate Hibernate是一个开源的Java持久化框架,它实现了Java Persistence API (JPA) 规范。Hibernate旨在帮助开发者通过面向对象的方式操作数据库,将对象映射到数据库表中,从而实现Java对象和数据库之间的映射关系。 Hibernate的优势 易于使用。Hib…

    Java 2023年5月19日
    00
  • 详解SpringBoot Starter作用及原理

    详解SpringBoot Starter作用及原理 简介 Spring Boot Starter简化了Spring Boot应用程序的依赖性管理,并提供了快速启动应用程序所需的所有依赖关系的打包方式。 什么是SpringBoot Starter 在Spring Boot项目开发中,我们可以参考Spring Boot Starter组织的maven工程来进行依…

    Java 2023年5月19日
    00
  • Android中Matrix用法实例分析

    Android中Matrix用法实例分析 什么是Matrix Matrix(矩阵)是Android中一个非常强大的变换工具类,可以通过Matrix类实现平移、旋转、缩放、扭曲等多种变换效果。一个Matrix对象可以对一个Bitmap、View或Drawable(图片对象)进行变换,让它们显示效果更加丰富。 Matrix的常见操作 new Matrix() 在…

    Java 2023年5月26日
    00
  • Java编程环境搭建和变量基本使用图文教程

    Java编程环境搭建和变量基本使用 简介 Java是一种常见的编程语言,需要搭建相应的开发环境和掌握基本的语法知识,才能对其进行编程操作。本篇攻略将详细介绍Java编程环境搭建和变量基本使用,帮助初学者快速上手。 环境搭建 下载和安装Java JDK 首先,需要从Oracle官网下载相应的Java开发套件(JDK)。下载后,在电脑上安装即可。安装过程中需要注…

    Java 2023年5月26日
    00
  • Java Swing最详细基础知识总结

    Java Swing最详细基础知识总结 什么是Java Swing Java Swing是一个GUI工具包,用于在Java应用程序中创建可视化用户界面。它提供了许多功能强大的组件,包括按钮、文本框、标签和表格等,使得我们可以快速方便的创建GUI界面,对于Java开发者来说是非常重要的工具。 Java Swing组件 Java Swing提供了许多GUI组件,…

    Java 2023年5月26日
    00
  • SpringBoot各种注解详解

    下面我将为您讲解“SpringBoot各种注解详解”的完整攻略,包含以下内容: Spring Boot的注解概述 常用注解解释与使用示例 自定义注解解释与使用示例 Spring Boot的注解概述 在Spring Boot中,有几百个注解可供使用。不过,我们只需要了解并掌握其中的一小部分。Spring Boot中的注解可以分为以下几类: 核心注解:用于Spr…

    Java 2023年5月15日
    00
  • Java中的异步与线程池解读

    Java中的异步与线程池解读 什么是异步? 异步是指一个方法调用不会阻塞当前线程,而是立即返回,然后在另一个线程上执行。由于异步方法不会阻塞当前线程,所以可以提高系统的并发能力,避免系统因等待I/O等操作而造成的阻塞。 在Java中,异步通常是指使用线程池来执行一些耗时的任务。Java 5引入了java.util.concurrent包,其中提供的Excut…

    Java 2023年5月18日
    00
  • Java spring定时任务详解

    Java Spring定时任务详解 Java Spring 定时任务是一种非常常用的任务调度方式,能够帮助我们自动化完成一些重复性、定期性的任务。本文将详细介绍 Java Spring 定时任务的使用方法和实现原理。 定时任务的基本概念 Java Spring 定时任务是指在指定的时间点或时间间隔内,自动执行指定的任务。我们可以通过 Spring 提供的@S…

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