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

Java中如何对静态方法JobQueue.getByte()实现互斥?

Java多线程互斥问题:确保JobQueue.getByte()单线程访问避免重复值

你的核心问题是JobQueue.getByte()方法的临界区未被完整同步。当前代码中,多个线程可同时进入方法,读取同一个nextByte值后各自修改,导致返回重复的byte数组;同时直接返回数组引用的操作,会让后续修改覆盖已返回的内容,进一步加剧重复问题。

解决方案1:用synchronized修饰静态方法

直接给getByte()加synchronized修饰符,锁的是JobQueue.class对象,确保同一时间只有一个线程执行整个方法的逻辑:

修改后的JobQueue类关键代码:

public class JobQueue{
    private static volatile Byte[] nextByte; 
    private static final Byte realMin = 0;
    private static final Byte realMax = (byte) 89; 

    // 省略initJobQueue和checkEndVal方法

    public static synchronized Byte[] getByte(){
        if(nextByte==null || checkEndVal(nextByte)) return null;

        // 克隆数组,避免返回引用被后续修改覆盖
        Byte[] currentByte = nextByte.clone();
    
        // 迭代递增逻辑
        for (int i = 0; i < nextByte.length; i++) {
            // 用equals避免Byte装箱类型的==比较问题
            if (nextByte[i].equals(realMax)){
                nextByte[i] = realMin;
            } else{
                nextByte[i]++;
                break;
            }
        }

        if(checkEndVal(nextByte)) nextByte=null;
        return currentByte;
    }
}

对应的ByteIterator的run方法可简化,无需额外加锁:

@Override
public void run(){ 
    Byte[] foo = JobQueue.getByte();
    while(foo != null){
        System.out.println(Arrays.toString(foo));
        foo = JobQueue.getByte();
    }
}

解决方案2:用ReentrantLock实现显式锁

如果需要更灵活的锁控制(如公平锁、超时锁),可使用显式锁包裹整个临界区:

修改后的JobQueue类关键代码:

import java.util.concurrent.locks.ReentrantLock;

public class JobQueue{
    private static volatile Byte[] nextByte; 
    private static final Byte realMin = 0;
    private static final Byte realMax = (byte) 89; 
    private static final ReentrantLock lock = new ReentrantLock();

    // 省略initJobQueue和checkEndVal方法

    public static Byte[] getByte(){
        lock.lock();
        try {
            if(nextByte==null || checkEndVal(nextByte)) return null;

            Byte[] currentByte = nextByte.clone();
        
            for (int i = 0; i < nextByte.length; i++) {
                if (nextByte[i].equals(realMax)){
                    nextByte[i] = realMin;
                } else{
                    nextByte[i]++;
                    break;
                }
            }

            if(checkEndVal(nextByte)) nextByte=null;
            return currentByte;
        } finally {
            lock.unlock(); // 确保锁一定会释放,避免死锁
        }
    }
}

你之前尝试失败的原因

  1. 同步范围不完整:仅在ByteIterator的后续调用加锁,但第一次getByte()调用在同步块外,存在初始竞争;且getByte()内部的读、复制、修改操作未被原子化,线程仍会交错执行。
  2. 数组引用直接返回:未克隆数组,导致返回的数组会被后续修改覆盖,看起来像是重复值(实际是同一数组被多次打印,内容已变更)。
  3. Byte类型比较问题:用==比较装箱后的Byte对象,会因缓存范围(-128~127)导致非预期的相等判断,改用equals()可避免此问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 07:43:15