三种方式来实现多线程连续打印abc

最近面试的时候会遇到这样的问题,竟然没有写出来,还是自己多练习吧 需求是这样的:

三个线程分别打印字符 abc,每个周期(即一次 abc)打印完成后换行

如果是让连续a b c 分开换行 只需要更改print的逻辑即可,不用在区分abc了

Synchronized

java 复制代码
package com.example.test;

public class Thread13 {
    private static final Object lock = new Object();
    private static int turn = 0; // 新增共享变量,记录当前该执行的线程编号

    public static void main(String[] args) {
        // 复用 print 方法创建线程
        Thread thread1 = new Thread(() -> print('a', 0));
        Thread thread2 = new Thread(() -> print('b', 1));
        Thread thread3 = new Thread(() -> print('c', 2));
        thread1.start();
        thread2.start();
        thread3.start();
    }

    // 合并后的打印方法
    public static void print(char c, int n) {
        for (int i = 0; i < 10; i++) {
            synchronized (lock) {
                // 使用 while 循环,确保线程被唤醒后再次检查条件
                while (turn != n) {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    }
                }
                if (c == 'c') {
                    System.out.println(c);
                } else {
                    System.out.print(c);
                }
                turn = (turn + 1) % 3; // 更新 turn 变量,让下一个线程执行
                lock.notifyAll();
            }
        }
    }
}

ReentrantLock 和 Condition

java 复制代码
package com.example.test;

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

public class thread14 {
    private static final int TOTAL_ITERATIONS = 10;
    private static final Lock lock = new ReentrantLock();
    private static final Condition conditionA = lock.newCondition();
    private static final Condition conditionB = lock.newCondition();
    private static final Condition conditionC = lock.newCondition();
    private static char current = 'a';

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> printChar('a', conditionA, conditionB, 'b'));
        Thread threadB = new Thread(() -> printChar('b', conditionB, conditionC, 'c'));
        Thread threadC = new Thread(() -> printChar('c', conditionC, conditionA, 'a'));

        threadA.start();
        threadB.start();
        threadC.start();

        // 等待所有线程完成
        try {
            threadA.join();
            threadB.join();
            threadC.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }

        System.out.println("\n所有线程打印完成!");
    }

    private static void printChar(char character, Condition currentCondition, Condition nextCondition, char nextCharacter) {
        for (int i = 0; i < TOTAL_ITERATIONS; i++) {
            lock.lock();
            try {
                while (current != character) {
                    currentCondition.await();
                }
                System.out.print(character);
                // 判断是否是第三个线程打印后换行
                if (character == 'c') {
                    System.out.println();
                }
                current = nextCharacter;
                nextCondition.signal();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            } finally {
                lock.unlock();
            }
        }
    }
}

Semaphore

java 复制代码
package com.example.test;

import java.util.concurrent.Semaphore;

public class thread15 {
    private static final int TOTAL_ITERATIONS = 10;
    private static Semaphore semaphoreA = new Semaphore(1);
    private static Semaphore semaphoreB = new Semaphore(0);
    private static Semaphore semaphoreC = new Semaphore(0);

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> printChar('a', semaphoreA, semaphoreB));
        Thread threadB = new Thread(() -> printChar('b', semaphoreB, semaphoreC));
        Thread threadC = new Thread(() -> printChar('c', semaphoreC, semaphoreA));

        threadA.start();
        threadB.start();
        threadC.start();

        // 等待所有线程完成
        try {
            threadA.join();
            threadB.join();
            threadC.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException(e);
        }

        System.out.println("\n所有线程打印完成!");
    }

    private static void printChar(char character, Semaphore currentSemaphore, Semaphore nextSemaphore) {
        for (int i = 0; i < TOTAL_ITERATIONS; i++) {
            try {
                currentSemaphore.acquire();
                System.out.print(character);
                // 判断是否是第三个线程打印后换行
                if (character == 'c') {
                    System.out.println();
                }
                nextSemaphore.release();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new RuntimeException(e);
            }
        }
    }
}
相关推荐
源码云商2 小时前
基于Spring Boot + Vue的母婴商城系统( 前后端分离)
java·spring boot·后端
还听珊瑚海吗5 小时前
基于SpringBoot的抽奖系统测试报告
java·spring boot·后端
你怎么知道我是队长8 小时前
Go语言标识符
后端·golang
sco528211 小时前
SpringBoot 自动装配原理 & 自定义一个 starter
java·spring boot·后端
海风极客13 小时前
《Go小技巧&易错点100例》第三十三篇
开发语言·后端·golang
养军博客13 小时前
Spring boot 简单开发接口
java·spring boot·后端
计算机学姐15 小时前
基于SpringBoot的在线教育管理系统
java·vue.js·spring boot·后端·mysql·spring·mybatis
有梦想的攻城狮16 小时前
spring中的@Value注解详解
java·后端·spring·value注解
编程乐趣17 小时前
基于.Net Core开发的GraphQL开源项目
后端·.netcore·graphql
阿乾之铭17 小时前
Spring Boot 中的重试机制
java·spring boot·后端