当前位置: 首页 > news >正文

两个线程循环打印奇偶数

题目要求:两个线程循环打印奇偶数。

1.示例1:

输入:7

输出:

OddThread: 1
EvenThread: 2
OddThread: 3
EvenThread: 4
OddThread: 5
EvenThread: 6
OddThread: 7

2.示例2:

输入:5

输出:

OddThread: 1
EvenThread: 2
OddThread: 3
EvenThread: 4
OddThread: 5

附代码:

一、方法一:ReentrantLock + Condition

class PrintOddEven { // 成员变量(字段),用于存储对象状态,在整个类中都可以使用 // 表示当前要打印的数字,是从1开始打印 private int num = 1; // 表示结尾数字 private final int max; // 可重入锁 private final ReentrantLock lock = new ReentrantLock(); // 创建一个与该锁绑定的等待队列oddCondition,用于管理线程的等待和唤醒 private final Condition oddCondition = lock.newCondition(); // 奇数线程的等待队列 private final Condition evenCondition = lock.newCondition(); // 偶数线程的等待队列 public PrintOddEven(int max) { // 构造方法参数,用于从外部接收传入的值 this.max = max; // 把参数的值赋给成员变量 } // 奇数线程 public void printOdd() { while (num <= max) { // 循环没超过最大值的时候才打印 lock.lock(); // 获取锁 try { if (num % 2 != 0) { // 如果是奇数 // 打印该奇数 System.out.println(Thread.currentThread().getName() + ": " + num); num++; // 唤醒偶数线程 evenCondition.signal(); } // 如果是偶数 else { // 奇数线程等待 oddCondition.await(); } // 捕获await()线程在等待期间,其他线程调用interrupt()抛出的InterruptedException异常 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } } public void printEven() { while (num <= max) { lock.lock(); try { if (num % 2 == 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; oddCondition.signal(); } else { evenCondition.await(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } } }

二、方法二:Synchronized + wait/notify

class PrintOddEven { private int num = 1; private final int max; private final Object lock = new Object(); public PrintOddEven(int max) { this.max = max; } public void printOdd() { synchronized (lock) { while (num <= max) { if (num % 2 != 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } } public void printEven() { synchronized (lock) { while (num <= max) { if (num % 2 == 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } } }

三、方法三:使用信号量 Semaphore(最简洁)

class PrintOddEven { private int num = 1; private final int max; private final Semaphore oddSemaphore = new Semaphore(1); private final Semaphore evenSemaphore = new Semaphore(0); public PrintOddEven(int max) { this.max = max; } public void printOdd() { while (num <= max) { try { oddSemaphore.acquire(); if (num <= max) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; } evenSemaphore.release(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } public void printEven() { while (num <= max) { try { evenSemaphore.acquire(); if (num <= max) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; } oddSemaphore.release(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } }

ACM模式:

一、方法一:ReentrantLock + Condition

import java.util.Scanner; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; class PrintOddEven { // 成员变量(字段),用于存储对象状态,在整个类中都可以使用 // 表示当前要打印的数字,是从1开始打印 private int num = 1; // 表示结尾数字 private final int max; // 可重入锁 private final ReentrantLock lock = new ReentrantLock(); // 创建一个与该锁绑定的等待队列oddCondition,用于管理线程的等待和唤醒 private final Condition oddCondition = lock.newCondition(); // 奇数线程的等待队列 private final Condition evenCondition = lock.newCondition(); // 偶数线程的等待队列 public PrintOddEven(int max) { // 构造方法参数,用于从外部接收传入的值 this.max = max; // 把参数的值赋给成员变量 } // 奇数线程 public void printOdd() { while (num <= max) { // 循环没超过最大值的时候才打印 lock.lock(); // 获取锁 try { if (num % 2 != 0) { // 如果是奇数 // 打印该奇数 System.out.println(Thread.currentThread().getName() + ": " + num); num++; // 唤醒偶数线程 evenCondition.signal(); } // 如果是偶数 else { // 奇数线程等待 oddCondition.await(); } // 捕获await()线程在等待期间,其他线程调用interrupt()抛出的InterruptedException异常 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } } public void printEven() { while (num <= max) { lock.lock(); try { if (num % 2 == 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; oddCondition.signal(); } else { evenCondition.await(); } } catch (InterruptedException e) { Thread.currentThread().interrupt(); } finally { lock.unlock(); } } } } public class Main { public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); // 传入参数n,用于后续构造方法接收参数max,并把参数的值赋值给成员变量this.max(private final int max) PrintOddEven printOddEven = new PrintOddEven(n); // ""里存放的是线程名称,会被子函数的Thread.currentThread().getName()获取到 Thread oddThread = new Thread(() -> printOddEven.printOdd(), "OddThread"); Thread evenThread = new Thread(() -> printOddEven.printEven(), "EvenThread"); oddThread.start(); evenThread.start(); oddThread.join(); evenThread.join(); scanner.close(); } }

二、方法二:Synchronized + wait/notify

import java.util.Scanner; class PrintOddEven { private int num = 1; private final int max; private final Object lock = new Object(); public PrintOddEven(int max) { this.max = max; } public void printOdd() { synchronized (lock) { while (num <= max) { if (num % 2 != 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } } public void printEven() { synchronized (lock) { while (num <= max) { if (num % 2 == 0) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; lock.notify(); } else { try { lock.wait(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } } } public class Main { public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); // 读取最大值 int n = scanner.nextInt(); PrintOddEven printOddEven = new PrintOddEven(n); // 创建两个线程 Thread oddThread = new Thread(() -> printOddEven.printOdd(), "OddThread"); Thread evenThread = new Thread(() -> printOddEven.printEven(), "EvenThread"); // 启动线程 oddThread.start(); evenThread.start(); // 等待线程结束 oddThread.join(); evenThread.join(); scanner.close(); } }

三、方法三:使用信号量 Semaphore(最简洁)

import java.util.Scanner; import java.util.concurrent.Semaphore; class PrintOddEven { private int num = 1; private final int max; private final Semaphore oddSemaphore = new Semaphore(1); private final Semaphore evenSemaphore = new Semaphore(0); public PrintOddEven(int max) { this.max = max; } public void printOdd() { while (num <= max) { try { oddSemaphore.acquire(); if (num <= max) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; } evenSemaphore.release(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } public void printEven() { while (num <= max) { try { evenSemaphore.acquire(); if (num <= max) { System.out.println(Thread.currentThread().getName() + ": " + num); num++; } oddSemaphore.release(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } public class Main { public static void main(String[] args) throws InterruptedException { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); PrintOddEven printOddEven = new PrintOddEven(n); Thread oddThread = new Thread(() -> printOddEven.printOdd(), "OddThread"); Thread evenThread = new Thread(() -> printOddEven.printEven(), "EvenThread"); oddThread.start(); evenThread.start(); oddThread.join(); evenThread.join(); scanner.close(); } }
http://www.jsqmd.com/news/720884/

相关文章:

  • 禾川HCQ0-1100-D PLC从开箱到跑通第一个CANopen轴:Codesys配置避坑全记录
  • 英语阅读_How can we develop our own style
  • 017、PCIe数据包结构:TLP、DLLP与Ordered Sets
  • 如何在OBS中实现专业级面部跟踪?2025最新插件完整指南
  • Claude Pulse:实时监控AI编程助手请求的VS Code扩展
  • Kimi K2.6 + Claude 多代理路由栈
  • 算法训练营第十六天 | 反转字符串 II
  • 抖音下载神器:5分钟掌握批量无水印下载技巧
  • 认识CPU篇
  • 风控特征缓存怎么设计?一次讲清热点特征、批量查询、缓存失效与一致性边界
  • 怎么让 AI 听懂你的话?——同一个 AI,为什么他用得比你好 倍
  • Hermes Agent 15 个隐藏特性
  • 深度学习进阶:预训练权重到底是个啥?看完这篇你就懂了(上篇)
  • 2026年3月优质的盐雾试验箱厂家推荐,高低温交变量热试验箱/高低温试验箱,盐雾试验箱厂商推荐 - 品牌推荐师
  • 别再傻傻重启电脑了!Google Drive大文件下载失败的5个真正原因与保姆级修复指南
  • 【车载C#中控实时通信黄金标准】:20年汽车电子专家亲授低延迟、高可靠通信架构设计(含CAN-FD+WebSocket双模实测数据)
  • 别再死磕开题!
  • SteamDeck_rEFInd:终极多系统引导方案,让Steam Deck变身全能设备
  • WRF输出变量管理避坑指南:从iofields配置到多流输出,一次讲清常见错误
  • 期刊合规插图这样做
  • RFG技术在机器人视觉动作规划中的应用与优化
  • 构建人格化AI聊天系统:从提示工程到向量记忆的实战指南
  • 5分钟免费体验:如何用Deep3D将普通2D视频变成震撼3D立体大片?
  • 3步搞定黑苹果:OpCore-Simplify零代码配置终极指南
  • 六西格玛在哪些行业应用广泛? - 众智商学院官方
  • 论文党必备:用TexStudio 4.6.3 + TeX Live 2023在Win11上打造高效LaTeX写作环境
  • GTNH汉化包:3步解锁百万字中文体验的完整指南
  • 答辩前3小时,我用百考通AI高效搞定毕业答辩PPT
  • EDITREWARD:多维度图像编辑评估技术解析
  • 知网+维普双平台过AIGC检测怎么选?嘎嘎降一份订单一次到位实测! - 我要发一区