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
相关推荐
QQ_1880838006 小时前
基于Python和django的贫困地区儿童在线帮扶系统
开发语言·python·django
计算机毕业设计开发6 小时前
django高校公寓管理系统--附源码64226
java·c++·spring boot·python·spring cloud·django·php
季明洵6 小时前
Java中哈希
java·算法·哈希
组合缺一6 小时前
Claude Code Agent Skills vs. Solon AI Skills:从工具增强到框架规范的深度对齐
java·人工智能·python·开源·solon·skills
学海无涯书山有路7 小时前
Android ViewBinding 新手详解(Java 版)—— 结合 ViewModel+LiveData 实战
android·java·开发语言
jaysee-sjc7 小时前
【练习十】Java 面向对象实战:智能家居控制系统
java·开发语言·算法·智能家居
哪里不会点哪里.7 小时前
Spring Boot 启动原理深度解析
java·spring boot·后端
零基础的修炼7 小时前
算法---常见位运算总结
java·开发语言·前端
蜂蜜黄油呀土豆7 小时前
Java虚拟机内存模型解析与内存管理问题
java·jvm·内存管理·内存泄漏·内存溢出
wgslucky7 小时前
sm2 js加密,java服务器端解密
java·开发语言·javascript