Java 多线程循环打印

文章目录

  • 一、标志变量 + 互斥锁
  • 二、标志变量 + synchronized
  • 三、标志变量 + 互斥锁 + 条件变量
  • 四、原子变量
  • 五、信号量


一、标志变量 + 互斥锁

标志变量用于标识当前应该是哪个线程进行输出,互斥锁用于保证对标志变量的互斥访问。

public class Main {
    private static int currentThread = 0;  // 标志变量
    private static final Lock lock = new ReentrantLock();  // 互斥锁

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> print("A", 0));
        Thread threadB = new Thread(() -> print("B", 1));
        Thread threadC = new Thread(() -> print("C", 2));

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

    private static void print(String message, int threadId) {
        try {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                while (threadId != currentThread) {
                    lock.unlock();
                    Thread.sleep(1);  // 让权等待,非必需
                    lock.lock();
                }
                System.out.print(message);
                currentThread = (currentThread + 1) % 3;
                lock.unlock();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

二、标志变量 + synchronized

通过在非静态方法以当前类作为锁可以避免显式的锁定义。

public class Main {

    public static void main(String[] args) {
        Print print = new Print();
        Thread threadA = new Thread(() -> print.loopPrint("A", 0));
        Thread threadB = new Thread(() -> print.loopPrint("B", 1));
        Thread threadC = new Thread(() -> print.loopPrint("C", 2));

        threadA.start();
        threadB.start();
        threadC.start();
    }
}
public class Print {
    private int currentThread = 0;  // 标志变量

    public void loopPrint(String message, int threadId) {
        try {
            for (int i = 0; i < 10; i++) {
                synchronized (this) {
                    while (threadId != currentThread) {
                        this.wait();
                    }
                    System.out.print(message);
                    currentThread = (currentThread + 1) % 3;
                    this.notifyAll();
                }
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

三、标志变量 + 互斥锁 + 条件变量

public class Main {
    private static int currentThread = 0;  // 标志变量
    private static final Lock lock = new ReentrantLock();  // 互斥锁
    private static final Condition condition = lock.newCondition();  // 条件变量

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> print("A", 0));
        Thread threadB = new Thread(() -> print("B", 1));
        Thread threadC = new Thread(() -> print("C", 2));

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

    private static void print(String message, int threadId) {
        try {
            for (int i = 0; i < 10; i++) {
                lock.lock();
                while (threadId != currentThread) {
                    condition.await();
                }
                System.out.print(message);
                currentThread = (currentThread + 1) % 3;
                condition.signalAll();
                lock.unlock();
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

四、原子变量

AtomicInteger 通过 CAS、volatilenative 方法保证了原子操作,同时避免了 synchronized 的高开销。

public class Main {
    private static final AtomicInteger currentThread = new AtomicInteger(0);  // 原子变量

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> print("A", 0));
        Thread threadB = new Thread(() -> print("B", 1));
        Thread threadC = new Thread(() -> print("C", 2));

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

    private static void print(String message, int threadId) {
        for (int i = 0; i < 10; i++) {
            while (threadId != currentThread.get()) {
                Thread.yield();  // 让权等待
            }
            System.out.print(message);
            currentThread.set((currentThread.get() + 1) % 3);
        }
    }
}

五、信号量

public class Main {
    private static final Semaphore semaphoreA = new Semaphore(1);
    private static final Semaphore semaphoreB = new Semaphore(0);
    private static final Semaphore semaphoreC = new Semaphore(0);

    public static void main(String[] args) {
        Thread threadA = new Thread(() -> print("A", semaphoreA, semaphoreB));
        Thread threadB = new Thread(() -> print("B", semaphoreB, semaphoreC));
        Thread threadC = new Thread(() -> print("C", semaphoreC, semaphoreA));

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

    private static void print(String message, Semaphore currentSemaphore, Semaphore nextSemaphore) {
        for (int i = 0; i < 10; i++) {
            try {
                currentSemaphore.acquire();
                System.out.print(message);
                nextSemaphore.release();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

在这里插入图片描述

你可能感兴趣的:(Java,java,多线程)