0

I'm trying to write in parallel an image which gets modified each iteration of a loop. The code looks like:

ExecutorService pool = Executors.newFixedThreadPool(8);
for (int i = array.length - 1; i > 0; i--) 
{
            pool.execute(() -> {
                ImageIO.write(bufferedImage, "JPG", fileName + i);
            });
            //Operations on the image...
}

The problem is that the image gets written just at its initial state (i=array.length) and at its final (i=1), but it actually writes the numbers of files it should (array.length times). So my question is, do I have to synchronize something on the image I'm writing? Aren't the objects state snapshotted and saved in memory once the Task gets into the queue? Or do tasks get the state of the object at the time of their actual execution?

Mattia Monari
  • 158
  • 1
  • 3
  • 9

2 Answers2

1

Task get state on moment of execution.

There is no straightforward way to get snapshot of object in java.

talex
  • 17,973
  • 3
  • 29
  • 66
  • Thanks @talex. Do you know if there's a Runnable implementation which gets the state of the object at the moment of it's scheduling? – Mattia Monari Oct 02 '22 at 07:41
1

You are changing the image before each Runnable has an opportunity to save the state of the image at the time you set up the sub-task. To avoid this problem you could make a copy of the image before setting up each runnable as follows:

BufferedImage imageCopy = copyImage(bufferedImage);
pool.execute(() -> {
    ImageIO.write(imageCopy, "JPG", fileName + i);
});

See these answers for possible implementations of copyImage(BufferedImage) and conditions / restrictions: Clone image How to clone image

DuncG
  • 12,137
  • 2
  • 21
  • 33