Using booleans for synchronization

Is the following code thread safe when accessing a list concurrently?
Does volatile meet the criteria to add any value here?

   class concurrentList{

        private AtomicBoolean locked = new AtomicBoolean(true);
        volatile List<Integer> list=new LinkedList<Integer>();
        long start = System.currentTimeMillis();
        long end = start + 60*100;


        public void push(int e){
            while(!locked.get());
            list.add(e);
            while(!locked.compareAndSet(true,false));
        }

        public int pop(){
            int elem;
            while(locked.get());
            elem=(Integer)list.remove(0);
            while(!locked.compareAndSet(false,true));
            return elem;
        }
....
}

      

+3


source to share


4 answers


No, it is not thread safe. The two calling threads push()

can perfectly read as blocked as true and then append simultaneously to the linked list. Since LinkedList is not thread safe, your code is not thread safe.



To block, use blocking, not AtomicBoolean.

+2


source


In such cases, I would recommend using ReadWriteLock . This lock has two uses. When readLock is enabled, reading is not allowed until the write lock is locked. Read lock is not blocking:

class concurrentList{
    ReadWriteLock lock =new ReentrantReadWriteLock();

    private AtomicBoolean locked = new AtomicBoolean(true);
    volatile List<Integer> list=new LinkedList<Integer>();
    long start = System.currentTimeMillis();
    long end = start + 60*100;


    public void push(int e){
        lock.writeLock().lock();
        try{
          list.add(e);
        } finally {
            lock.writeLock().unlock();
        }
    }

    public int pop(){
        lock.readLock().lock();
        try {
        int elem;

        elem=(Integer)list.remove(0);
        } finally {
           lock.readLock().unlock();
        }
        return elem;
    }

      



....}

+1


source


In this particular case, I would use synchronization for the methods and would not be changed for the variable according to [this question][1]

class concurrentList {

    private AtomicBoolean locked = new AtomicBoolean(true);
    List<Integer> list=new LinkedList<Integer>();
    long start = System.currentTimeMillis();
    long end = start + 60*100;


    public synchronized void push(int e){
        while(someLock.notCondition()); //only an example
        list.add(e);
        someLock.notify();
    }

    public synchronized int pop(){
        int elem;
        while(someLock.notCondition());
        elem=(Integer)list.remove(0);
        someLock.notify()
        return elem;
    }
....
}

      

0


source


Adding more to the one already added in the answer i.e. for any parallel programming there are three concepts you need to consider when writing thread safe programming. When a parallel program is written incorrectly, bugs tend to fall into one of three categories: Aomicity , Visibility, or Order .

Atomicity : refers to which actions and sets of actions have indivisible effects. This is usually seen as mutual exclusion.

Visibility : Determines when the effects of one stream are visible to others.

Order : Determines when actions in one thread may be seen out of order relative to another

In your code, the first problem is dropping all of the above concepts. You are not using locking, so visibility and order will not be guaranteed. For thread safety, you can use ReadWriteLock

in parallel API. Or is there a non-blocking linked list available that compareAndset will use.

0


source







All Articles