Gemini永久会员 三个线程(A、B、C)交替执行

要实现三个线程(A、B、C)交替执行(即按顺序A→B→C→A→B→C...循环),可以通过线程同步机制(如wait()/notify()ReentrantLock+Condition)或使用Semaphore信号量来控制。以下是两种常见实现方式:


方法1:使用 wait()notify()

通过共享锁和条件变量实现线程交替执行:

java 复制代码
public class AlternateThreads {
    private static final Object lock = new Object();
    private static int state = 0; // 0:A, 1:B, 2:C

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (state % 3 != 0) { // 检查是否是A的轮次
                        try { lock.wait(); } catch (InterruptedException e) {}
                    }
                    System.out.print("A");
                    state++;
                    lock.notifyAll(); // 唤醒其他线程
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (state % 3 != 1) { // 检查是否是B的轮次
                        try { lock.wait(); } catch (InterruptedException e) {}
                    }
                    System.out.print("B");
                    state++;
                    lock.notifyAll();
                }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                synchronized (lock) {
                    while (state % 3 != 2) { // 检查是否是C的轮次
                        try { lock.wait(); } catch (InterruptedException e) {}
                    }
                    System.out.print("C");
                    state++;
                    lock.notifyAll();
                }
            }
        }).start();
    }
}

输出示例ABCABCABC...

关键点

  1. 共享变量 state 记录当前轮次。
  2. 每个线程通过 wait() 等待自己的轮次,执行后通过 notifyAll() 唤醒其他线程。
  3. synchronized 确保线程安全。

方法2:使用 ReentrantLock + Condition(更灵活)

通过显式锁和条件变量实现更清晰的交替控制:

java 复制代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class AlternateThreadsWithLock {
    private static ReentrantLock lock = new ReentrantLock();
    private static Condition conditionA = lock.newCondition();
    private static Condition conditionB = lock.newCondition();
    private static Condition conditionC = lock.newCondition();
    private static int state = 0; // 0:A, 1:B, 2:C

    public static void main(String[] args) {
        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (state % 3 != 0) {
                        conditionA.await();
                    }
                    System.out.print("A");
                    state++;
                    conditionB.signal(); // 唤醒B
                } catch (InterruptedException e) {}
                finally { lock.unlock(); }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (state % 3 != 1) {
                        conditionB.await();
                    }
                    System.out.print("B");
                    state++;
                    conditionC.signal(); // 唤醒C
                } catch (InterruptedException e) {}
                finally { lock.unlock(); }
            }
        }).start();

        new Thread(() -> {
            while (true) {
                lock.lock();
                try {
                    while (state % 3 != 2) {
                        conditionC.await();
                    }
                    System.out.print("C");
                    state++;
                    conditionA.signal(); // 唤醒A
                } catch (InterruptedException e) {}
                finally { lock.unlock(); }
            }
        }).start();
    }
}

优势

  • 每个线程有独立的 Condition,避免不必要的唤醒(比 notifyAll() 更高效)。
  • 代码结构更清晰,易于扩展。

方法3:使用 Semaphore 信号量

通过信号量控制线程的执行顺序:

java 复制代码
import java.util.concurrent.Semaphore;

public class AlternateThreadsWithSemaphore {
    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) {
        new Thread(() -> {
            while (true) {
                try {
                    semaphoreA.acquire();
                    System.out.print("A");
                    semaphoreB.release();
                } catch (InterruptedException e) {}
            }
        }).start();

        new Thread(() -> {
            while (true) {
                try {
                    semaphoreB.acquire();
                    System.out.print("B");
                    semaphoreC.release();
                } catch (InterruptedException e) {}
            }
        }).start();

        new Thread(() -> {
            while (true) {
                try {
                    semaphoreC.acquire();
                    System.out.print("C");
                    semaphoreA.release();
                } catch (InterruptedException e) {}
            }
        }).start();
    }
}

原理

  • 初始时 semaphoreA 有一个许可,其他信号量为0。
  • 每个线程执行后释放下一个线程的信号量,形成循环。

总结

  • 简单场景 :用 wait()/notify()Semaphore
  • 复杂场景 :用 ReentrantLock + Condition(更灵活高效)。
  • 关键点:确保线程按顺序释放资源,避免死锁或竞争条件。

根据需求选择合适的方法即可!

相关推荐
许彰午19 小时前
CacheSQL(二):主从复制——OpLog 环形缓冲区与故障自动恢复
java·数据库·缓存
陈随易19 小时前
AI时代,你还在坚持手搓文章吗
前端·后端·程序员
Bat U20 小时前
JavaEE|多线程初阶(七)
java·开发语言
大鱼七成饱20 小时前
VMware NAT模式下固定内网IP(附详细图文)
后端
薪火铺子20 小时前
微服务认证方案对比与选型
微服务·云原生·架构
运维全栈笔记21 小时前
K8S部署Redis高可用全攻略:1主2从3哨兵架构实战
redis·docker·云原生·容器·架构·kubernetes·bootstrap
IT_陈寒1 天前
Vue的这个响应式陷阱,我debug了一整天才爬出来
前端·人工智能·后端
兔子零10241 天前
手把手教你在 Claude Code 中接入 DeepSeek-V4
后端
掌心向暖RPA自动化1 天前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭1 天前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器