0

It is possible to add elements to arraylist while other thread, reading the arraylist in same time, get notified about this changes?

For example i have an arraylist in main thread. There is 4 elements:

    ArrayList<Integer> list = new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);

Meantime, other thread add elements in same list:

     Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            for (int i = 5; i < 10; i++) {
                list.add(i);
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    });
    thread.start();

Now i start reading them like:

    for (int i : list) {
        System.out.println(i);
        Thread.sleep(2000);
    }

I want to read all elements from 1 to 9, but this is not work. How i can pull off this? Maybe i should put synchronized block in this code, but where should i?

Aleks
  • 17
  • 3
  • https://stackoverflow.com/a/10640753/3824919 – Tom Nov 08 '19 at 09:48
  • What do you mean by "get notified"? – MC Emperor Nov 08 '19 at 09:49
  • I mean that elements, added in other thread will be available in main thread while i reading them. i.e. at start i have 4 elements in arraylist. I'm statring iteration. But it won't stop on 4, and instead go on up to 9. – Aleks Nov 08 '19 at 10:04

3 Answers3

0

There is a list implementation in java.util.concurrent. CopyOnWriteArrayList.

RainHunter
  • 308
  • 4
  • 12
0

This can't be done using an ArrayList but it sounds like what you need is some queue.
For that, you can use one of the implementations of Queue. for example, take ConcurrentLinkedQueue which can work well in your multithread scanario.

Nir Levy
  • 12,750
  • 3
  • 21
  • 38
0

Even though the use case is not quite clear and it is mostly not advised to deal with shared resources with such an approach, in order to be able to read all the elements within the list you must wait for the second thread to terminate (thus having populated all the elements within the collection).

You can use Thread#join to make the main thread wait for thread termination:

// ...
thread.start();
thread.join();
// ...
tmarwen
  • 15,750
  • 5
  • 43
  • 62