You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java多线程实现:3线程存整数、过滤奇偶的代码开发求助

我来帮你完善这个多线程整数分类的Java程序!你的需求是三个线程协作:一个生产整数,另外两个分别筛选偶数和奇数存入对应列表。这里核心要解决线程安全和线程间协作的问题,我给你写了完整的可运行代码,同时拆解关键细节:

import java.util.LinkedList;

public class Manage {
    private final Object lock = new Object();
    private final LinkedList<Integer> intStorage = new LinkedList<>();
    private final LinkedList<Integer> evens = new LinkedList<>();
    private final LinkedList<Integer> odds = new LinkedList<>();
    // 标记生产线程是否完成任务,volatile保证多线程可见性
    private volatile boolean isProducingDone = false;

    // 生产线程:往intStorage存入整数
    public void intCollection() throws InterruptedException {
        try {
            // 这里模拟生产1-100的整数,你可以根据需求修改范围
            for (int i = 1; i <= 100; i++) {
                synchronized (lock) {
                    intStorage.add(i);
                    System.out.println("生产线程存入:" + i);
                    // 通知等待的筛选线程有新数据了
                    lock.notifyAll();
                }
                // 模拟生产间隔,让多线程协作效果更直观
                Thread.sleep(50);
            }
        } finally {
            synchronized (lock) {
                isProducingDone = true;
                // 通知所有筛选线程生产已结束,不用再等待
                lock.notifyAll();
            }
        }
    }

    // 筛选偶数的线程
    public void filterEvens() throws InterruptedException {
        synchronized (lock) {
            while (true) {
                // 当存储列表为空且生产未完成时,进入等待
                while (intStorage.isEmpty() && !isProducingDone) {
                    lock.wait();
                }
                // 生产完成且列表为空,退出循环结束线程
                if (intStorage.isEmpty() && isProducingDone) {
                    break;
                }
                // 取出第一个元素判断是否为偶数
                Integer num = intStorage.removeFirst();
                if (num % 2 == 0) {
                    evens.add(num);
                    System.out.println("偶数线程存入:" + num);
                } else {
                    // 是奇数就放回列表,让奇数线程处理
                    intStorage.addFirst(num);
                    // 通知奇数线程有数据待处理
                    lock.notifyAll();
                }
            }
        }
    }

    // 筛选奇数的线程
    public void filterOdds() throws InterruptedException {
        synchronized (lock) {
            while (true) {
                // 当存储列表为空且生产未完成时,进入等待
                while (intStorage.isEmpty() && !isProducingDone) {
                    lock.wait();
                }
                // 生产完成且列表为空,退出循环结束线程
                if (intStorage.isEmpty() && isProducingDone) {
                    break;
                }
                // 取出第一个元素判断是否为奇数
                Integer num = intStorage.removeFirst();
                if (num % 2 != 0) {
                    odds.add(num);
                    System.out.println("奇数线程存入:" + num);
                } else {
                    // 是偶数就放回列表,让偶数线程处理
                    intStorage.addFirst(num);
                    // 通知偶数线程有数据待处理
                    lock.notifyAll();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Manage manager = new Manage();

        // 创建并启动三个线程
        Thread producer = new Thread(() -> {
            try {
                manager.intCollection();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("生产线程被中断");
            }
        });

        Thread evenFilter = new Thread(() -> {
            try {
                manager.filterEvens();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("偶数线程被中断");
            }
        });

        Thread oddFilter = new Thread(() -> {
            try {
                manager.filterOdds();
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                System.out.println("奇数线程被中断");
            }
        });

        producer.start();
        evenFilter.start();
        oddFilter.start();

        // 等待所有线程执行完毕
        producer.join();
        evenFilter.join();
        oddFilter.join();

        // 输出最终分类结果
        System.out.println("\n最终偶数列表:" + manager.evens);
        System.out.println("最终奇数列表:" + manager.odds);
    }
}
关键细节拆解
  • 线程安全保障:所有操作共享列表的代码都包裹在synchronized (lock)块中,确保同一时间只有一个线程能修改或访问这些列表,避免竞态条件导致的数据混乱。
  • 等待/通知机制:
    • 筛选线程在存储列表为空且生产未完成时,调用lock.wait()进入等待状态,避免空轮询浪费CPU资源。
    • 生产线程每次存入数据后,调用lock.notifyAll()唤醒所有等待的筛选线程;生产完成后再次通知,让筛选线程知道可以退出。
  • 非目标数据处理:比如偶数线程取出奇数时,会把数据放回存储列表头部,并通知其他线程,确保每个数据都能被正确分类。
  • 中断处理:每个线程都捕获了InterruptedException并重置中断状态,符合Java线程中断的最佳实践。
  • volatile关键字:isProducingDone用volatile修饰,保证生产线程修改这个状态后,其他线程能立刻看到最新值,不会出现线程无限等待的情况。

内容的提问来源于stack exchange,提问作者user9679684

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:45:02