-1

When I run this code, the output is "something is added" and then infinite loop ...

My program should print:

something is added

something is printed

I don't understand why the program can not exit while loop

import java.util.LinkedList;
public class Test {
static LinkedList<String> list = new LinkedList<String>();
public static void main(String[] args) {
    new Thread(new Runnable() {

        @Override
        public void run() {
            while(list.isEmpty()); // here is the loop
            System.out.println("something is printed"+list.get(0));
        }
    }).start(); 
    new Thread(new Runnable() {

        @Override
        public void run() {
            try{
                Thread.sleep(200);
                list.add("something");
                System.out.println("something is added");
            }catch (Exception e) {}
        }
    }).start(); 
  }
}

I am looking for solution and explanation

Thanks A lot

AndroidDev
  • 39
  • 1
  • 7
  • You've hinted to the answer in your title: there's no synchronization. – shmosel May 11 '17 at 21:54
  • I don't understand. what is the solution? – AndroidDev May 11 '17 at 21:57
  • Although I have an idea what's wrong with your program - or how to improve it - you don't make clear what is actually happening with it and what the problem is. It would be nice if you could tell what output you see, and if it is the same for multiple runs. – M. le Rutte May 11 '17 at 21:58
  • @M.leRutte It's in the first line of the question... – shmosel May 11 '17 at 22:00

1 Answers1

-1

In order for threads to communicate and share data safely, they have to be properly synchronized. The simplest way to do that in your example is to wrap your list in a synchronized wrapper:

static List<String> list = Collections.synchronizedList(new LinkedList<>());
shmosel
  • 49,289
  • 6
  • 73
  • 138
  • This doesn't explain *why* the code doesn't exit, because, it should if you read the statements. Adding syncrhonization is not the reason, adding a simple `System.out.println(list.isEmpty());` makes the code exit correctly too, – M. le Rutte May 11 '17 at 22:11
  • 2
    @M.leRutte It doesn't exit because of memory visibility, which is a synchronization problem. The `println()` statement accidentally fixes the problem because it contains a `synchronized` block which flushes memory. – shmosel May 11 '17 at 22:15
  • that's weird! what is going on! :) – AndroidDev May 11 '17 at 22:16
  • if I add, while(list.isEmpty()) System.out.print(""); IT WORKS. Thanks you all – AndroidDev May 11 '17 at 22:20
  • By the way, you should really consider using a `java.util.concurrent.BlockingQueue`, having a loop running around until something's put in the list only helps out maxing the CPU. – M. le Rutte May 11 '17 at 22:21
  • @AndroidDev Not everything that "works" is correct. Another way of fixing the visibility problem is to declare `list` as `volatile`. But the code would still be wrong because it structurally modifies a shared list without synchronization. – shmosel May 11 '17 at 22:22