我正在尝试从使用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'}
我不确定发生了什么。 有人可以解释一下这种行为吗?
谢谢,
阿玛尔
答案 0 :(得分:1)
我在这里假设问题:你的entryRequest是在循环的每次迭代中创建的(在主线程中)。因此,当线程池执行程序来调用你的lamdba时,它可能已经改变了。你有绝对无法控制谁在这个变量时访问。
不是构造一个匿名的Runnable类,而是更好地编写自己的Runnable实现,将entryRequest作为参数传递给它(例如通过构造函数或setter),然后让run方法对这个传递的变量进行操作。这可确保每个线程在其自己的entryRequest实例上运行。