0

I am trying to add elements in t linkedBlockingQueue from a thread, created using lambda, When I poll the queue using the take method, I can see that the last values entered from the thread overrides the previous values.

Following is the code :-

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;
}

After polling the queue, I get the following:-

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

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

I am not sure what is happening. Can some one please explain this behaviour ??

Thanks,

Amar

2
  • Not clear to me what the constructor EntryBarricade does (who starts the runnable and when?). Nor what the method entryRequestQueuingService.Queue(entryRequest) does. Commented Oct 23, 2016 at 13:07
  • Since obviously you run for each iteration of your main loop a new thread to operate on the entryRequestQueuingService there must be synchronization when accessing common resources (as the Queue). Commented Oct 23, 2016 at 13:09

1 Answer 1

1

I assume the problem here: your entryRequest is created in each iteration of your loop (in the main thread). So when the thread pool executor comes to call your lamdba it might have changed already. You have absolute no control who access when this variable.

Instead of constructing an anonymous Runnable class better write your own implementation of Runnable, pass the entryRequest as parameter to it (e.g by constructor or setter) and let the run method then operate on this passed variable. This ensures that each thread operates on its own entryRequest instance.

Sign up to request clarification or add additional context in comments.

1 Comment

You Sir are a certified Genius!!!!!! I see the problem now....it works!!!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.