使用布尔值进行同步

时间:2017-06-03 06:36:30

标签: java concurrency java.util.concurrent

以下代码对List的并发访问是否是线程安全的? volatile是否符合条件在这里添加任何值?

   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;
        }
....
}

4 个答案:

答案 0 :(得分:2)

不,它不是线程安全的。调用class Eq (Target b) => Matchable b where ...的两个线程可以完全读取锁定为true,然后同时添加到链表。由于LinkedList不是线程安全的,因此您的代码不是线程安全的。

要锁定,请使用锁,而不是AtomicBoolean。

答案 1 :(得分:1)

Inn这样的情况我建议使用ReadWriteLock。这个锁有两个用途。当readLock打开时,不允许读取,直到释放写锁定。读取锁定是非阻塞的:

holidays

.... }

答案 2 :(得分:0)

在这种特殊情况下,我会使用synchronized作为方法,而不是根据[this question][1]

的变量使用volatile

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;
    }
....
}

答案 3 :(得分:0)

添加更多已经添加的答案即对于任何并发编程三个概念,在编写线程安全编程时需要考虑。当并发程序未正确编写时,错误往往属于以下三类之一: Aomicity 可见性订购

原子性:处理哪些行为和行动具有不可分割的影响。通常认为是互斥。

可见性:确定何时另一个线程可以看到一个线程的效果。

订购:确定何时可以看到一个线程中的操作与另一个线程中的操作无序发生

在你的代码第一期中,它没有提到上面提到的所有概念。你没有使用锁,因此无法确保可见性和排序。 对于线程安全,您可以在并发API中使用ReadWriteLock。或者有可用的非阻塞链表,它将使用compareAndset。