Java lambdas LinkedBlockingQueue 意外行为

Java lambdas LinkedBlockingQueue unexpected behaviour

我正在尝试从使用 lambda 创建的线程向 t linkedBlockingQueue 添加元素,当我使用 take 方法轮询队列时,我可以看到从线程输入的最后一个值覆盖了以前的值。

代码如下:-

public List<EntryBarricade> entryBarricades() {
    List<EntryBarricade> entryBarricades = new ArrayList<>();
    EntryBarricade entryBarricade;
    Runnable runnable;

    for (int i =0;i<=1;i++) {
        EntryRequest entryRequest =  new EntryRequest("Barricade-"+i);
        runnable = new Runnable() {
            @Override
            public void run() {
                ExecutorService entryGate1 = Executors.newSingleThreadExecutor();
                for (int j =0;j<=1;j++) {
                    entryGate1.submit(() -> {
                        entryRequest.setVehicleId(Thread.currentThread().getName()
                                + " " + new Double(Math.random()));
                        entryRequestQueuingService.Queue(entryRequest);
                    });
                }
            }
        };
        entryBarricade = new EntryBarricade("Barricade-"+i, runnable);
        entryBarricades.add(entryBarricade);
    }
    return entryBarricades;
}

轮询队列后,我得到以下信息:-

请求{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.9091480024731418'} 请求{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'} 请求{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.7978996055410615'} 请求{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'}

请求{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'} 请求{barricadeId='Barricade-0', vehicleId='pool-2-thread-1 0.05687657229049259'} 请求{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'} 请求{barricadeId='Barricade-1', vehicleId='pool-3-thread-1 0.2734508504023724'}

我不确定发生了什么。 有人可以解释一下这种行为吗??

谢谢,

阿马尔

我假设这里存在问题:您的 entryRequest 是在循环的每次迭代中创建的(在主线程中)。因此,当线程池执行程序调用您的 lamdba 时,它可能已经更改。您绝对无法控制谁访问此变量。

与其构造一个匿名的 Runnable class,不如编写您自己的 Runnable 实现,将 entryRequest 作为参数传递给它(例如通过构造函数或 setter)并让 运行方法然后对这个传递的变量进行操作。这确保每个线程都在其自己的 entryRequest 实例上运行。