문제

Is CopyOnWriteArrayList list enough to use as a collection for shopping-cart. As I understand it is thread-safe and the iterator is guaranteed not to throw ConcurrentModificationException when during iteration another thread removes a product. For example:

    ...
    CopyOnWriteArrayList<Product> products = (CopyOnWriteArrayList<Product>)session.getAttribute("PRODUCTS");
    products.addIfAbsent(aProduct);
    ...

P.S. I found synchronization approaches using synchronized (session) {...} but it seams a little ugly when I need synchronize session access everywhere when I work with shopping-cart as offered in this article

도움이 되었습니까?

해결책 2

I think you are good to go with CopyOnWriteArrayList in the scenario you described. It has sufficient guarantees to work as thread safe Implementations including visibility. Yes it is true that it gives the snapshot of the data when you call iterate. But there is always a race condition, while you remove it before reading or read it before removing.CopyOnWriteArrayList is a fine implementation which can be used where reads >>> writes, which i think is the case in shopping cart use case.

It is just that while iterating you will not see changes (write operation). You should understand nothing is free, if you want to see the changes while traversing you need to properly synchronize your every iteration with any write operation which is will compromise perfomance. Trust me you will gain nothing. Most of the concurrent Data structures gives weakly consistent state on iteration see (ConcurrentSkipListSet). So use either CopyOnWriteArrayList, ConcurrentSkipListSet you are good to go. I think sets are better for your use case i.e to avoid duplicate orders ..

다른 팁

You need to understand what CopyOnWriteArrayList provides.

It provides you a snapshot and does not give you real time view of backend array.

It weakens the contract of visibility, it says that you will not get ConcurrentModificationException but also says that if other thread removes some element, the effect will not be visible to other thread which is iterating maybe, because on addition or removal the original array is not mutated or touched and a new one is created on every operation that mutates the backing array.

Is CopyOnWriteArrayList list enough to use as a collection for shopping-cart.

Depends.

If this behavior is acceptable in your scenario then you can use it, but if you want visibility guarantee you may have to use explicit locking.

Is CopyOnWriteArrayList list enough to use as a collection for shopping-cart

No because it depends on what you need to synchronize. Think about what must not happen at the same time.

As I understand it is thread-safe and the iterator is guaranteed not to throw ConcurrentModificationException when during iteration another thread removes a product.

You will not get a ConcurrentModificationException because every modification you do to the list will create a copy of the list. A thread that iterates will use the most current copy. But that thread can't assume that a product is still actually in the list when it sees it. It might have been removed in the most current version.

Or maybe to use "heavier artillery" like following, in all places when accessing to shopping-cart collection.

    AtomicReference<List<Product>> productListRef = 
        AtomicReference<List<Product>>)session.getAttribute("PRODUCTS");

    List<Product> oldList;
    List<Product> newList;

    do {
        oldList = productListRef.get();
        newList = new ArrayList<>(oldList);
        newList.add(aProduct);
    } while (!ref.compareAndSet(oldList, newList));

Thank a lot for previous answers!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top