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

后端笔试题-多线程JUC相关

JUC题

两个线程A和B,A线程打印1,3,5,7,9 B线程打印2,4,6,8,10,两个线程同时运行,要求打印结果为1,2,3,4,5,6.

本题主要考察线程的通信以及多线程的知识

public class AlternatingPrint {private static final Object lock = new Object();private static int currentNumber = 1; // 当前需要打印的数字private static final int MAX_NUMBER = 99; // 最大打印数字public static void main(String[] args) {Thread threadA = new Thread(() -> {while (currentNumber <= MAX_NUMBER) {synchronized (lock) {while (currentNumber % 2 == 0) { // 如果当前数字是偶数,等待try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Thread A prints: " + currentNumber);currentNumber++;lock.notify(); // 唤醒另一个线程}}});Thread threadB = new Thread(() -> {while (currentNumber <= MAX_NUMBER) {synchronized (lock) {while (currentNumber % 2 != 0) { // 如果当前数字是奇数,等待try {lock.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Thread B prints: " + currentNumber);currentNumber++;lock.notify(); // 唤醒另一个线程}}});threadA.start();threadB.start();}

a打印完后就加1,进入等待状态,让b醒来进行打印,b打印完进入等待,唤醒a进行打印,交替操作实现

package threadDemo;import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;/*** @Author 泽* @Date 2025/2/28 13:50* 写两个线程A和B,A线程打印1,3,5,7,9 B线程打印2,4,6,8,10* 两个线程同时运行,要求打印结果为1,2,3,4,5,6.。。。。。*/
public class AlternatingPrint {private static final ReentrantLock lock = new ReentrantLock();private static final Condition oddCondition = lock.newCondition();private static final Condition evenCondition = lock.newCondition();private static int currentNumber = 1; // 当前需要打印的数字private static final int MAX_NUMBER = 99; // 最大打印数字public static void main(String[] args) {Thread threadA = new Thread(() -> {while (true) {lock.lock();try {// 打印奇数并唤醒偶数线程if (currentNumber <= MAX_NUMBER && currentNumber % 2 == 1) {System.out.println("Thread A prints: " + currentNumber);currentNumber++;evenCondition.signal(); // 唤醒偶数线程} else if (currentNumber > MAX_NUMBER) {evenCondition.signal(); // 唤醒偶数线程使其退出break;} else {oddCondition.await(); // 等待奇数打印机会}} catch (InterruptedException e) {Thread.currentThread().interrupt();break;} finally {lock.unlock();}}});Thread threadB = new Thread(() -> {while (true) {lock.lock();try {// 打印偶数并唤醒奇数线程if (currentNumber <= MAX_NUMBER && currentNumber % 2 == 0) {System.out.println("Thread B prints: " + currentNumber);currentNumber++;oddCondition.signal(); // 唤醒奇数线程} else if (currentNumber > MAX_NUMBER) {oddCondition.signal(); // 唤醒奇数线程使其退出break;} else {evenCondition.await(); // 等待偶数打印机会}} catch (InterruptedException e) {Thread.currentThread().interrupt();break;} finally {lock.unlock();}}});threadA.start();threadB.start();}
}

ReentranLock的Candition实现精确的线程唤醒,避免了synchronized的随机唤醒问题,并且增加线程中断的处理等

计算1-10000之间有多少个素数,越快越好

package threadDemo;public class PrimeCalculator {private static final int START = 1; // 素数范围的起始值private static final int END = 100000; // 素数范围的结束值private static final int NUM_THREADS = 8; // 线程数量public static void main(String[] args) {System.out.println("Number of available processors: " + NUM_THREADS);System.out.println("Calculating prime numbers between " + START + " and " + END);long startTime = System.currentTimeMillis();// 将范围平均分配给每个线程int rangePerThread = (END - START) / NUM_THREADS;Thread[] threads = new Thread[NUM_THREADS];PrimeCounter[] counters = new PrimeCounter[NUM_THREADS];for (int i = 0; i < NUM_THREADS; i++) {int startRange = START + i * rangePerThread;int endRange = (i == NUM_THREADS - 1) ? END : startRange + rangePerThread;counters[i] = new PrimeCounter(startRange, endRange);threads[i] = new Thread(counters[i]);threads[i].start();}// 等待所有线程完成try {for (Thread thread : threads) {thread.join();}} catch (InterruptedException e) {e.printStackTrace();}long endTime = System.currentTimeMillis();System.out.println("Total time taken: " + (endTime - startTime) + " ms");// 统计所有线程的素数数量int totalPrimes = 0;for (PrimeCounter counter : counters) {totalPrimes += counter.getPrimeCount();}System.out.println("Total prime numbers found: " + totalPrimes);}
}// 素数计数器类
class PrimeCounter implements Runnable {private final int start;private final int end;private int primeCount;public PrimeCounter(int start, int end) {this.start = start;this.end = end;this.primeCount = 0;}@Overridepublic void run() {for (int num = start; num <= end; num++) {if (isPrime(num)) {primeCount++;}}System.out.println("Thread " + Thread.currentThread().getName() + " found " + primeCount + " primes in range [" + start + ", " + end + "]");}public int getPrimeCount() {return primeCount;}// 判断一个数是否为素数private boolean isPrime(int num) {if (num <= 1) return false;if (num == 2) return true;if (num % 2 == 0) return false;for (int i = 3; i <= Math.sqrt(num); i += 2) {if (num % i == 0) return false;}return true;}
}
  • PrimeCalculator类首先定义了三个核心常量:素数范围的起始值START(1)、结束值END(100000),以及线程数量NUM_THREADS(8)。
  • 根据线程数量来划分每个线程要判断的数据,明确每个线程的工作,并且定义计数器类继承Runnable接口实现基数
  • 主线程通过thread.join()等待所有子线程执行完毕,确保所有素数统计完成后再汇总结果:

遍历所有PrimeCounter实例,累加每个线程的素数计数得到totalPrimes

计算并输出总耗时(endTime - startTime)和总素数数量

通过“参数配置→任务拆分→并行计算→结果汇总”四步,实现了素数查找任务的多线程并行加速。

http://www.xdnf.cn/news/19660.html

相关文章:

  • 用滑动窗口与线性回归将音频信号转换为“Token”序列:一种简单的音频特征编码方法
  • 全栈智算系列直播回顾 | 智算中心对网络的需求与应对策略(下)
  • Linux开发必备:yum/vim/gcc/make全攻略
  • 大模型微调显存内存节约方法
  • 【ComfyUI】图像描述词润色总结
  • 基于若依框架前端学习VUE和TS的核心内容
  • 函数、数组与 grep + 正则表达式的 Linux Shell 编程进阶指南
  • windows10专业版系统安装本地化mysql服务端
  • AI公共数据分析完整实战教程:从原始数据到商业洞察【网络研讨会完整回放】
  • golang -- viper
  • Go语言运维实用入门:高效构建运维工具
  • 洽洽的“成本龙卷风”与渠道断层
  • MVC问题记录
  • Python备份实战专栏第5/6篇:Docker + Nginx 生产环境一键部署方案
  • 【机器学习入门】4.4 聚类的应用——从西瓜分类到防控,看无监督学习如何落地
  • Mac上如何安装mysql
  • 阿里云代理商:轻量应用服务器介绍及搭建个人博客教程参考
  • 【赵渝强老师】阿里云大数据MaxCompute的体系架构
  • Git基础使用和PR贡献
  • 02-Media-1-acodec.py 使用G.711编码和解码音频的示例程序
  • 电子电气架构 --- 智能电动车EEA电子电气架构(上)
  • 时序数据库IoTDB:为何成为工业数据管理新宠?
  • (Mysql)MVCC、Redo Log 与 Undo Log
  • 《探索C++11:现代C++语法的性能革新(上篇)》
  • C++11 ——— lambda表达式
  • 前端必看:为什么同一段 CSS 在不同浏览器显示不一样?附解决方案和实战代码
  • 血缘元数据采集开放标准:OpenLineage Guides 使用 Apache Airflow® 和 OpenLineage + Marquez 入门
  • 使用Spring Boot对接印度股票市场API开发实践
  • Linux初始——Vim
  • [VLDB 2025]阿里云大数据AI平台多篇论文被收录