我在这里写了一个辅助函数,方便查看结果。

public class SleepUtils {
    public static final void second(long seconds)
    {
        try {
            Thread.sleep(seconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

1. 使用synchronized

/*
 * @Description: 文件描述
 * @Version: 1.0
 * @Author: YueXuanzi
 * @Date: 2024-10-16 19:59:48
 * @LastEditors: YueXuanzi
 * @LastEditTime: 2024-10-17 09:17:39
 * @心得体会: 无
 */
public class SwapABC {
    static Object lock = new Object();
    static Object lock2 = new Object();
    static Object lock3 = new Object();

    public static void soutA(){
        while(true){
            synchronized(lock){
                synchronized(lock2){
                    System.out.println("A");
                    SleepUtils.second(1);
                    lock2.notify();
                    // System.out.println("唤醒B");
                }
                try {
                    // System.out.println("A准备等待");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void soutB(){
        while(true){
            synchronized(lock2){
                synchronized(lock3){
                    System.out.println("B");
                    SleepUtils.second(1);
                    lock3.notify();
                    // System.out.println("唤醒C");
                }
                try {
                    // System.out.println("B准备等待");
                    lock2.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }   
        
    }
    public static void soutC(){
        while(true){
            synchronized(lock3){
                synchronized(lock){
                    System.out.println("C");
                    SleepUtils.second(1);
                    lock.notify();
                    // System.out.println("唤醒A");
                }
                try {
                    // System.out.println("C准备等待");
                    lock3.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        new Thread(()->{soutA();}).start();
        SleepUtils.second(1);
        new Thread(()->{soutB();}).start();
        SleepUtils.second(1);
        new Thread(()->{soutC();}).start();
    }
}

2. 使用信号量

import java.util.concurrent.Semaphore;

public class SwapABCOne {
    private final Semaphore A = new Semaphore(1);

    private final Semaphore B = new Semaphore(0);

    private final Semaphore C = new Semaphore(0);

    public void printA() {
        try {
            A.acquire();
            System.out.println("A");
            B.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printB(){
        try {
            B.acquire();
            System.out.println("B");
            C.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void printC(){
        try {
            C.acquire();
            System.out.println("C");
            A.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwapABCOne swapABCOne = new SwapABCOne();
        new Thread(() -> {
            while(true) {
                swapABCOne.printA();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();

        new Thread(() -> {
            while(true) {
                swapABCOne.printB();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(() -> {
            while(true) {
                swapABCOne.printC();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }).start(); 
    }
}

3. 使用ReentrantLock + Condition

这里就与之前的类似了,我觉得没必要去写了

ReentrantLock lock = new ReentrantLock();
Condition A = lock.newCondition();
A.await();
A.signal();
lock.lock();
lock.unlock();

参考链接

多线程循环打印ABC

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐