我正在尝试从使用lambda创建的线程向tlinkedBlockingQueue中添加元素,当我使用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类更好地编写您自己的Runnable实现,不如将entryRequest作为参数传递给它(例如,通过构造函数或setter),然后让run方法对该传递的变量进行操作。这样可以确保每个线程在其自己的entryRequest实例上运行。
关于java - Java Lambdas LinkedBlockingQueue意外行为,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40203177/