三种方式来实现多线程连续打印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);
            }
        }
    }
}
相关推荐
冒泡的肥皂11 分钟前
强大的ANTLR4语法解析器入门demo
后端·搜索引擎·编程语言
IT_陈寒36 分钟前
Element Plus 2.10.0 重磅发布!新增Splitter组件
前端·人工智能·后端
有梦想的攻城狮1 小时前
spring中的@RabbitListener注解详解
java·后端·spring·rabbitlistener
Java水解1 小时前
MySQL DQL全面解析:从入门到精通
后端·mysql
Aurora_NeAr1 小时前
Apache Spark详解
大数据·后端·spark
程序员岳焱1 小时前
Java 程序员成长记(二):菜鸟入职之 MyBatis XML「陷阱」
java·后端·程序员
hello早上好1 小时前
BeanFactory 实现
后端·spring·架构
我命由我123451 小时前
Spring Boot 项目集成 Redis 问题:RedisTemplate 多余空格问题
java·开发语言·spring boot·redis·后端·java-ee·intellij-idea
面朝大海,春不暖,花不开1 小时前
Spring Boot消息系统开发指南
java·spring boot·后端
程序员岳焱1 小时前
Java 程序员成长记(三):菜鸟入职之@Transactional「罢工」
java·后端·编程语言