java多线程实现有序输出ABC

yizhihongxing

要实现有序输出ABC,可以通过以下几种方式实现:

方式一:使用synchronized关键词

Java中,synchronized关键字可以锁住对象,只允许一个线程访问同一时间内执行的代码块。我们可以使用该关键字来实现对三个线程输出ABC顺序的控制。

public class ABCPrinter implements Runnable {
    private char ch;
    private Object prev;
    private Object self;

    public ABCPrinter(char ch, Object prev, Object self) {
        this.ch = ch;
        this.prev = prev;
        this.self = self;
    }

    public void run() {
        synchronized (prev) {
            while (true) {
                synchronized (self) {
                    System.out.print(ch);
                    self.notify();
                }
                try {
                    prev.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Object a = new Object();
        Object b = new Object();
        Object c = new Object();
        ABCPrinter pa = new ABCPrinter('A', c, a);
        ABCPrinter pb = new ABCPrinter('B', a, b);
        ABCPrinter pc = new ABCPrinter('C', b, c);

        new Thread(pa).start();
        Thread.sleep(10);//保证初始ABC的启动顺序
        new Thread(pb).start();
        Thread.sleep(10);//保证初始ABC的启动顺序
        new Thread(pc).start();
        Thread.sleep(10);//保证初始ABC的启动顺序
    }
}
  • 首先,我们定义了一个类 ABCPrinter,实现了 Runnable 接口,线程对象可以通过该接口创建。
  • 这个类包含了两个 Object 对象,prev 和 self。prev 存储前一个线程的锁对象,self 存储当前线程的锁对象。
  • 在 run() 方法中,我们使用 synchronized(prev) 进入同步锁,如果当前线程不符合执行条件,就让它 wait(),否则就在 synchronized(self) 代码块中输出字符,并通过 self.notify() 唤醒其他等待线程。
  • 此外,我们还在 main 方法中分别启动了三个线程。在每个线程启动前都让程序 sleep 一段时间,保证启动顺序为 ABC。

方式二:使用Lock与Condition

在Java中,Lock与Condition可以实现与synchronized关键词类似的线程同步功能。我们可以使用Lock与Condition来实现多线程的有序输出ABC。

public class ABCPrinter {
    private Lock lock = new ReentrantLock();
    private Condition conditionA = lock.newCondition();
    private Condition conditionB = lock.newCondition();
    private Condition conditionC = lock.newCondition();

    private int currentThread = 0;

    public void printA() throws InterruptedException {
        lock.lock();
        try {
            while (currentThread != 0) {
                conditionA.await();
            }
            System.out.print("A");
            currentThread = 1;
            conditionB.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void printB() throws InterruptedException {
        lock.lock();
        try {
            while (currentThread != 1) {
                conditionB.await();
            }
            System.out.print("B");
            currentThread = 2;
            conditionC.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void printC() throws InterruptedException {
        lock.lock();
        try {
            while (currentThread != 2) {
                conditionC.await();
            }
            System.out.print("C");
            currentThread = 0;
            conditionA.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        final ABCPrinter printer = new ABCPrinter();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    printer.printA();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    printer.printB();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    printer.printC();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
  • 首先,我们定义了一个类 ABCPrinter,该类包含了Lock与Condition对象,用于实现线程同步。
  • ABCPrinter 类还包含了一个 currentThread 状态变量,表示上一个输出的字符。
  • 在 printA、printB、printC 方法中,我们获取锁,如果当前线程不符合执行条件,就调用 await() 方法,让线程进入休眠状态。否则输出字符,并修改 currentThread 状态变量,最后调用 signalAll() 方法,唤醒其他等待线程。

以上就是两种实现多线程有序输出ABC的解决方案。可以根据实际需要来选择适合自己的方式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java多线程实现有序输出ABC - Python技术站

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

相关文章

  • 微信小程序实现一键登录

    实现微信小程序的一键登录,可以使用微信开放平台提供的第三方授权登录功能。以下是具体的实现攻略: 1. 准备工作 首先要申请微信开放平台的帐号并完成认证 在开放平台中创建自己的小程序,并获取小程序的 AppID 和 AppSecret 2. 添加授权登录 将微信提供的授权登录组件添加到小程序中。 <!– index.wxml –> <bu…

    Java 2023年5月23日
    00
  • Java实现深度搜索DFS算法详解

    Java实现深度搜索DFS算法详解 DFS简介 深度搜索(Depth First Search, DFS)是一种用于遍历或搜索树或图的算法。其基本思想是从根节点出发,尽可能深的遍历每一个节点,直到没有下一个未访问的节点,然后回溯到最近的未访问节点,并继续访问其它节点。 DFS算法流程 DFS算法的流程如下: 将起始节点添加到栈中 判断栈是否为空,如果为空则退…

    Java 2023年5月19日
    00
  • jsp实现点击help打开chm文件

    下面是jsp实现点击help打开chm文件的完整攻略。 1. 准备工作 在服务器上搭建好jsp网站,并在网站根目录下准备好help.chm文件。 2. 编写jsp页面 在需要添加帮助文档链接的jsp页面中,添加以下代码: <a href="${pageContext.request.contextPath}/help.chm"&gt…

    Java 2023年6月15日
    00
  • Java设计模式之观察者模式(Observer模式)介绍

    Java设计模式之观察者模式(Observer模式)介绍 观察者模式,也叫做发布订阅模式,是一种常用的设计模式。它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,当一个对象发生改变时,所有依赖于它的对象都将得到通知并被自动更新。 观察者模式的结构 观察者模式由四个角色组成:抽象主题角色、具体主题角色、抽象观察者角色和具体观察者角色。 抽象主题…

    Java 2023年6月15日
    00
  • 序列化实现对象的拷贝

    提到拷贝,大家第一时间想到的可能都是克隆模式的深克隆,因为这个模式在面试中出现的机率非常高,同时实现的方式也比较容易:对象的类实现Cloneable接口并且重写clone()方法即可。但是在实际情况中克隆模式有时候其实并不适合用来拷贝对象,因为如果有很多的实体类都需要拷贝,这个时候难道把这些实体类全都实现克隆模式?这是不提倡的,这个时候可以使用序列化方式来实…

    Java 2023年4月19日
    00
  • SpringBoot嵌入式Servlet容器与定制化组件超详细讲解

    SpringBoot嵌入式Servlet容器与定制化组件超详细讲解 本文将介绍SpringBoot中嵌入式Servlet容器的相关知识及如何定制化组件来实现对该容器的定制化配置。 嵌入式Servlet容器 在SpringBoot中,可以通过嵌入式Servlet容器来运行Web应用程序,而无需将其部署到外部容器中。嵌入式Servlet容器作为一个独立的进程,可…

    Java 2023年5月19日
    00
  • 使用SSM+Layui+Bootstrap实现汽车维保系统的示例代码

    下面就为大家介绍如何使用SSM+Layui+Bootstrap实现汽车维保系统的完整攻略。首先,我们将从环境搭建开始,分别介绍SSM框架、Layui和Bootstrap的使用方法和示例。 环境搭建 JDK 1.8及以上 Maven 3.X及以上 Tomcat 8.X及以上 Eclipse集成开发环境 以上环境安装配置完成后,我们就可以开始使用SSM+Layu…

    Java 2023年5月19日
    00
  • SpringBoot整合Spring Data JPA的详细方法

    Spring Boot整合Spring Data JPA的详细方法 Spring Data JPA是Spring Framework的一部分,它提供了一种方便的方式来访问和操作数据库。在Spring Boot应用程序中,可以使用Spring Data JPA来简化数据库访问。本文将详细介绍Spring Boot整合Spring Data JPA的详细方法,包…

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