Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make two threads take turns in modifying an arraylist?

The code you will see below is trying to achieve the following:

  • add "line 0" into arraylist
  • print the last item in the arraylist i.e. "line 0"
  • remove last item from arraylist

  • add "line 1" into arraylist

  • print the last item in the arraylist i.e. "line 1" remove last item from arraylist

...and so on without end.

So, the output I expect is simply:

line 0

line 1

..

..

However, what I get is a random amount of "line i"s where i is also random. Here's a sample output:

Line 0

Line 38919

Line 47726

Line 54271

then the program gets stuck in what appears to be a deadlock even though that doesn't make sense because the variable 'held' can only be true or false and either of those situations is supposed to allow one of the threads to do work.

import java.util.*;

public class Test {

     static boolean held = true;
     static ArrayList<String> line = new ArrayList<>();


     public static void main(String[] args) {

        new Thread() {
            @Override
            public void run() {
                int i = 0;
                while(true) {
                    if(held) {
                        line.add("Line " + i);
                        i++;
                        held = false;
                    }
                }
            }


        }.start();

        while(true) {
            if(!held) {
                System.out.println( line.get(line.size() - 1) );
                line.remove(line.size() - 1);
                held = true;

            }else continue;
        }

    }


}
like image 280
Dziugas Avatar asked Mar 17 '23 12:03

Dziugas


1 Answers

Likely the fact that your held variable is not volatile is causing the deadlock. The different cores on your computer will have their own memory caches, which are not necessarily updated concurrently. To make sure changes to held are visible to all threads, you should make it volatile. You could also use an AtomicBoolean, or synchronize access to the blocks of code.

like image 128
Thorn G Avatar answered Mar 20 '23 18:03

Thorn G