自学内容网 自学内容网

三个线程交替打印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();  // 解锁
            }
        }

    }

}

原文地址:https://blog.csdn.net/Mr_Richard/article/details/142976904

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!