当前位置: 首页 > article >正文

三个线程交替打印ABC

1. 使用Semaphore信号量实现线程同步

代码实现:

import java.util.concurrent.Semaphore;

public class PrinterTest {

    public static void main(String[] args) {
        Printer printer = new Printer(100);
        Thread a = new Thread(printer::printA, "Thread A");
        Thread b = new Thread(printer::printB, "Thread B");
        Thread c = new Thread(printer::printC, "Thread C");
        a.start();
        b.start();
        c.start();
    }
}

class Printer {
    // 使用Semaphore信号量实现线程同步
    private Semaphore semaphoreA = new Semaphore(1);
    private Semaphore semaphoreB = new Semaphore(0);
    private Semaphore semaphoreC = new Semaphore(0);
    private int num; // 打印数量

    public Printer(int num) {
        this.num = num;
    }

    public void printA() {
        print('A', semaphoreA, semaphoreB);
    }

    public void printB() {
        print('B', semaphoreB, semaphoreC);
    }

    public void printC() {
        print('C', semaphoreC, semaphoreA);
    }

    public void print(char c, Semaphore currentSemaphore, Semaphore nextSemaphore) {
        for (int i = 0; i < num; i++) {
            try {
                currentSemaphore.acquire();    // 阻塞当前线程
                System.out.println(Thread.currentThread().getName() + ":" + c); // 打印字母
                nextSemaphore.release();    // 唤醒下一个线程
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

    }

}

2. 使用ReentrantLock + Condition实现线程同步

代码实现:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class PrinterTest {

    public static void main(String[] args) {
        Printer printer = new Printer(100);
        Thread a = new Thread(printer::printA, "Thread A");
        Thread b = new Thread(printer::printB, "Thread B");
        Thread c = new Thread(printer::printC, "Thread C");
        a.start();
        b.start();
        c.start();
        // 先唤醒线程A对应的conditionA
        printer.init();

    }
}

class Printer {
    // 使用ReentrantLock + Condition实现线程同步
    private static ReentrantLock lock = new ReentrantLock();
    Condition conditionA = lock.newCondition();
    Condition conditionB = lock.newCondition();
    Condition conditionC = lock.newCondition();
    int threadIndex = 0;  // 0:A,1:B, 2:C
    private int num = 10; // 打印数量

    public Printer(int num) {
        this.num = num;
    }

    /**
     * 初始时优先选择A
     */
    public void init() {
        lock.lock();
        try {
            conditionA.signal();
            threadIndex = 0;
        } finally {
            lock.unlock();
        }
    }


    public void printA() {
        print(conditionA, conditionB, 0);
    }

    public void printB() {
        print(conditionB, conditionC, 1);
    }

    public void printC() {
        print(conditionC, conditionA, 2);
    }

    public void print(Condition currentCondition, Condition nextCondition, int currentIndex) {
        for (int i = 0; i < num; i++) {
            lock.lock();    // 加锁
            try {
                // 不是当前线程能打印的时机,阻塞当前线程
                while (currentIndex != threadIndex) {
                    currentCondition.await();
                }
                char c = (char) ('A' + threadIndex);
                System.out.println(Thread.currentThread().getName() + ":" + c);
                threadIndex = (threadIndex + 1) % 3;
                nextCondition.signal();  // 唤醒下一线程
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            } finally {
                lock.unlock();  // 解锁
            }
        }

    }

}

http://www.kler.cn/a/353555.html

相关文章:

  • 数据库序列的使用、常见场景与优劣势分析
  • 互联网架构变迁:从 TCP/IP “呼叫” 到 NDN “内容分发” 的逐浪之旅
  • uniapp:钉钉小程序需要录音权限及调用录音
  • “深入浅出”系列之QT:(6)如何在一个项目中调用另一个项目
  • Photon最新版本PUN 2.29 PREE,在无网的局域网下,无法连接自己搭建的本地服务器
  • Vue进阶(贰幺贰)npm run build多环境编译
  • Java读取PDF后做知识库问答_SpringAI实现
  • Vue基础(3)
  • 区块链积分系统:重塑支付安全与商业创新的未来
  • Java知识巩固(五)
  • visio导出pdf公式变形问题杂谈
  • 如何在 cPanel 中使用 PHP-FPM
  • 推荐一个可以免费上传PDF产品图册的网站
  • 【鸟类识别系统】Python+卷积神经网络算法+人工智能+深度学习+ResNet50算法+计算机课设项目
  • 缓存区是什么
  • Vue3 使用CryptoJS加密
  • 介绍 TensorFlow 的基本概念和使用场景(AI)
  • 关于拖拽时需要注意的细节
  • 多层感知机 MLP
  • 【优选算法篇】编织算法的流动诗篇:滑动窗口的轻盈之美
  • Golang | Leetcode Golang题解之第477题汉明距离总和
  • mqtt客户端订阅一直重复连接?
  • 详解SSH和bash
  • 【Linux】嵌入式Linux系统的组成、u-boot编译
  • 灵当CRM data/pdf.php 任意文件读取漏洞复现
  • 计算机网络(五)—— 运输层