0

I have been working on a little project with two threads. One generates content and places it in a Queue (in a static context). The other thread runs and waits for content in the queue to do something.

The Issue:

While the second thread is waiting for something to be placed in the queue, it seems to not be running, I will try to show this.

I am just curious is what is happening here.

_slices is a Queue : Queue<E> _slices = new LinkedList<E>();

Thread 2 run():

while ( true ) {
    if ( !Main._slices.isEmpty() ) {
            System.out.println( "Something in the Queue!" );
       } else if ( Main.doneQueuing ) {
            break;
       }
}

This code above will not do anything once an element is added to the queue.


Now, this code works:

while ( true ) {
    System.out.println( "As long as a process is done here it works" );
    if ( !Main._slices.isEmpty() ) {
            System.out.println( "Something in the Queue!" );
       } else if ( Main.doneQueuing ) {
            break;
       }
}
MichaelMitchell
  • 1,069
  • 2
  • 13
  • 38

2 Answers2

1

LinkedList in not thread safe. You have to do locking your self.

Let's try ConcurrentLinkedQueue or LinkedBlockingQueue

cat916
  • 1,363
  • 10
  • 18
1

Based on the provided information, I can only guess. I imagine your code looks as follows. The data structure _slices is shared between threads, there is a method push that adds an element to the shared data structure and is executed in one thread. And there is a method poll that checks if the data structure is not empty, and is executed in another thread.

class Foo {
    Queue<String> _slices = new ArrayDeque<>();
    void push(String element) {
        _slices.add(element);
    }
    void poll() {
        while (!_slices.empty()) {
            // ...
        }
    }
}

In the example above, there is a so-called data race. That means the Java Programming Language does not guarantee, that executions are sequentially consistent. There are still some guarantees. However, they are quite complicated.

In order to avoid the data race, you should use a data structure that supports concurrency, e.g. ConcurrentLinkedQueue or LinkedBlockingQueue. Or you should use some synchronization mechanisms in your code, e.g. synchronized blocks.

nosid
  • 48,932
  • 13
  • 112
  • 139
  • But why does the dependent thread recognize that an element was added (size is no longer 0) if there is a process (like a println) before the if statement. – MichaelMitchell Mar 30 '14 at 08:50
  • 1
    @MichaelMitchell: Because there is also some synchronization within _println_. That doesn't remove the _data race_. However, it changes the probability of the _race condition_. – nosid Mar 30 '14 at 08:52
  • I think this is a little over my current understanding. I will just go with your proposition. Thank you for your time. – MichaelMitchell Mar 30 '14 at 08:54