Java线程交替打印

多线程编程是计算机科学中一个重要的概念,它允许程序同时执行多个任务,提高了程序的并发性和效率。在Java中,线程是可以并发执行的基本单位。本文将介绍Java中线程交替打印的概念和实现方法,并提供相应的代码示例。

什么是线程交替打印?

线程交替打印是指多个线程按照一定规律交替执行打印操作。例如,有两个线程A和B,线程A负责打印奇数,线程B负责打印偶数。线程A打印完一个奇数后,线程B再打印一个偶数,然后线程A继续打印下一个奇数,如此循环执行。线程交替打印可以用来解决一些特定的问题,例如生产者-消费者问题、多线程计算等。

实现线程交替打印的方法

在Java中,实现线程交替打印的方法有多种,以下是两种常见的方法。

方法一:使用synchronized关键字和wait/notify机制

public class AlternatePrinting implements Runnable {
    private static final Object lock = new Object();
    private static volatile int count = 1;
    private int threadId;
    private int maxCount;

    public AlternatePrinting(int threadId, int maxCount) {
        this.threadId = threadId;
        this.maxCount = maxCount;
    }

    @Override
    public void run() {
        synchronized (lock) {
            while (count <= maxCount) {
                if (count % 2 == threadId) {
                    System.out.println("Thread " + threadId + ": " + count);
                    count++;
                    lock.notifyAll();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        Thread threadA = new Thread(new AlternatePrinting(1, 10));
        Thread threadB = new Thread(new AlternatePrinting(0, 10));
        threadA.start();
        threadB.start();
    }
}

在上述代码中,我们使用了一个共享的锁对象lock,以及一个计数器count。每个线程通过获取锁对象,判断当前的计数器是否满足打印条件,如果满足则打印当前计数器的值,并将计数器加1,然后唤醒其他线程;如果不满足,则当前线程进入等待状态,直到被唤醒。这样两个线程就可以交替执行打印操作。

方法二:使用Semaphore信号量

import java.util.concurrent.Semaphore;

public class AlternatePrinting implements Runnable {
    private static final Semaphore semaphoreA = new Semaphore(1);
    private static final Semaphore semaphoreB = new Semaphore(0);
    private static volatile int count = 1;
    private int threadId;
    private int maxCount;

    public AlternatePrinting(int threadId, int maxCount) {
        this.threadId = threadId;
        this.maxCount = maxCount;
    }

    @Override
    public void run() {
        while (count <= maxCount) {
            try {
                if (count % 2 == threadId) {
                    if (threadId == 0) {
                        semaphoreA.acquire();
                    } else {
                        semaphoreB.acquire();
                    }
                    System.out.println("Thread " + threadId + ": " + count);
                    count++;
                    if (threadId == 0) {
                        semaphoreB.release();
                    } else {
                        semaphoreA.release();
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        Thread threadA = new Thread(new AlternatePrinting(0, 10));
        Thread threadB = new Thread(new AlternatePrinting(1, 10));
        threadA.start();
        threadB.start();
    }
}

在上述代码中,我们使用了两个Semaphore对象semaphoreAsemaphoreB,分别用于控制两个线程的执行顺序。线程A先执行,因此初始化时semaphoreA的初始许可数设置为1,线程B需要等待线程A的许可释放,因此semaphoreB的初始许可数设置为0。每个线程在执行打印操作之前