Java中两个线程交替打印1-100

方式1:使用synchronized和wait()/notify()

java 复制代码
public class AlternatePrint {
    private int number = 1;
    private final Object lock = new Object();
    
    public void printOddEven() {
        // 奇数线程
        Thread thread1 = new Thread(() -> {
            synchronized (lock) {
                while (number <= 100) {
                    if (number % 2 == 1) {  // 打印奇数
                        System.out.println(Thread.currentThread().getName() + ": " + number++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                lock.notify();  // 唤醒可能还在等待的线程
            }
        }, "奇数线程");
        
        // 偶数线程
        Thread thread2 = new Thread(() -> {
            synchronized (lock) {
                while (number <= 100) {
                    if (number % 2 == 0) {  // 打印偶数
                        System.out.println(Thread.currentThread().getName() + ": " + number++);
                        lock.notify();
                    } else {
                        try {
                            lock.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                lock.notify();  // 唤醒可能还在等待的线程
            }
        }, "偶数线程");
        
        thread1.start();
        thread2.start();
    }
    
    public static void main(String[] args) {
        new AlternatePrint().printOddEven();
    }
}

方式2:使用ReentrantLock和Condition(更灵活)

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

public class AlternatePrintWithLock {
    private int number = 1;
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition oddCondition = lock.newCondition();  // 奇数条件
    private final Condition evenCondition = lock.newCondition(); // 偶数条件
    
    public void printOddEven() {
        // 打印奇数
        Thread oddThread = new Thread(() -> {
            lock.lock();
            try {
                while (number <= 100) {
                    if (number % 2 == 1) {
                        System.out.println("奇数线程: " + number++);
                        evenCondition.signal();  // 唤醒偶数线程
                    } else {
                        oddCondition.await();    // 等待
                    }
                }
                evenCondition.signal();  // 最后唤醒偶数线程,防止死锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        
        // 打印偶数
        Thread evenThread = new Thread(() -> {
            lock.lock();
            try {
                while (number <= 100) {
                    if (number % 2 == 0) {
                        System.out.println("偶数线程: " + number++);
                        oddCondition.signal();   // 唤醒奇数线程
                    } else {
                        evenCondition.await();   // 等待
                    }
                }
                oddCondition.signal();  // 最后唤醒奇数线程,防止死锁
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        
        oddThread.start();
        evenThread.start();
    }
    
    public static void main(String[] args) {
        new AlternatePrintWithLock().printOddEven();
    }
}

方式3:使用AtomicInteger和Semaphore(更简洁)

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

public class AlternatePrintWithSemaphore {
    private AtomicInteger number = new AtomicInteger(1);
    private Semaphore oddSemaphore = new Semaphore(1);   // 奇数信号量,初始有许可
    private Semaphore evenSemaphore = new Semaphore(0);  // 偶数信号量,初始无许可
    
    public void printOddEven() {
        // 打印奇数
        Thread oddThread = new Thread(() -> {
            while (number.get() <= 100) {
                try {
                    oddSemaphore.acquire();  // 获取奇数信号量
                    if (number.get() <= 100) {
                        System.out.println("奇数线程: " + number.getAndIncrement());
                    }
                    evenSemaphore.release(); // 释放偶数信号量
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        // 打印偶数
        Thread evenThread = new Thread(() -> {
            while (number.get() <= 100) {
                try {
                    evenSemaphore.acquire();  // 获取偶数信号量
                    if (number.get() <= 100) {
                        System.out.println("偶数线程: " + number.getAndIncrement());
                    }
                    oddSemaphore.release();   // 释放奇数信号量
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        
        oddThread.start();
        evenThread.start();
    }
    
    public static void main(String[] args) {
        new AlternatePrintWithSemaphore().printOddEven();
    }
}

方式4:通用模板类(可复用)

java 复制代码
public class AlternatePrintTemplate {
    private int num = 1;
    private final Object lock = new Object();
    
    public void alternatePrint(int max) {
        new Thread(() -> printNum(max, 1), "线程A").start();
        new Thread(() -> printNum(max, 0), "线程B").start();
    }
    
    private void printNum(int max, int remainder) {
        synchronized (lock) {
            while (num <= max) {
                // 使用位运算判断奇偶,性能更好
                if ((num & 1) == remainder) {
                    System.out.println(Thread.currentThread().getName() + ": " + num++);
                    lock.notifyAll();
                } else {
                    try {
                        lock.wait();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) {
        new AlternatePrintTemplate().alternatePrint(100);
    }
}

关键点说明:

  1. 线程同步:必须确保两个线程不会同时操作共享变量

  2. 线程通信:需要正确使用wait/notify或Condition进行线程间通信

  3. 边界条件:正确处理打印到100后两个线程都能正常退出

  4. 避免死锁:确保即使一个线程先结束,另一个线程也不会永久等待

推荐:

  • 对于简单场景,推荐使用方式1(synchronized)

  • 对于需要更精细控制的情况,推荐方式2(ReentrantLock)

  • 对于性能要求高的场景,推荐使用方式4的位运算判断奇偶

这些方法都能实现两个线程交替打印1-100,输出结果类似于:

java 复制代码
奇数线程: 1
偶数线程: 2
奇数线程: 3
偶数线程: 4
...
奇数线程: 99
偶数线程: 100
相关推荐
天若有情6739 分钟前
【C++原创开源】formort.h:一行头文件,实现比JS模板字符串更爽的链式拼接+响应式变量
开发语言·javascript·c++·git·github·开源项目·模版字符串
好家伙VCC13 分钟前
**发散创新:基于Python与ROS的机器人运动控制实战解析**在现代机器人系统开发中,**运动控制**是实现智能行为的核心
java·开发语言·python·机器人
2401_8274999913 分钟前
python项目实战09-AI智能伴侣(ai_partner_2-3)
开发语言·python
派葛穆15 分钟前
汇川PLC-Python与汇川easy521plc进行Modbustcp通讯
开发语言·python
程途知微1 小时前
ConcurrentHashMap线程安全实现原理全解析
java·后端
lzhdim1 小时前
SharpCompress:跨平台的 C# 压缩与解压库
开发语言·c#
嘿嘿嘿x31 小时前
Linux记录过程
linux·开发语言
Mars酱1 小时前
1分钟编写贪吃蛇 | JSnake贪吃蛇单机版
java·后端·开源
devpotato1 小时前
人工智能(四)- Function Calling 核心原理与实战
java·人工智能
默 语1 小时前
Records、Sealed Classes这些新特性:Java真的变简单了吗?
java·开发语言·python