• 【翻译二十二】java-并发之集合与原子变量


    Concurrent Collections

    The java.util.concurrent package includes a number of additions to the Java Collections Framework. These are most easily categorized by the collection interfaces provided:

    • BlockingQueue defines a first-in-first-out data structure that blocks or times out when you attempt to add to a full queue, or retrieve from an empty queue.
    • ConcurrentMap is a subinterface of java.util.Map that defines useful atomic operations. These operations remove or replace a key-value pair only if the key is present, or add a key-value pair only if the key is absent. Making these operations atomic helps avoid synchronization. The standard general-purpose implementation of ConcurrentMap isConcurrentHashMap, which is a concurrent analog of HashMap.
    • ConcurrentNavigableMap is a subinterface of ConcurrentMap that supports approximate matches. The standard general-purpose implementation of ConcurrentNavigableMap is ConcurrentSkipListMap, which is a concurrent analog of TreeMap.

    All of these collections help avoid Memory Consistency Errors by defining a happens-before relationship between an operation that adds an object to the collection with subsequent operations that access or remove that object.

    Atomic Variables

    The java.util.concurrent.atomic package defines classes that support atomic operations on single variables. All classes haveget and set methods that work like reads and writes on volatile variables. That is, a set has a happens-before relationship with any subsequent get on the same variable. The atomic compareAndSet method also has these memory consistency features, as do the simple atomic arithmetic methods that apply to integer atomic variables.

    To see how this package might be used, let's return to the Counter class we originally used to demonstrate thread interference:

    class Counter {
        private int c = 0;
    
        public void increment() {
            c++;
        }
    
        public void decrement() {
            c--;
        }
    
        public int value() {
            return c;
        }
    
    }
    

    One way to make Counter safe from thread interference is to make its methods synchronized, as in SynchronizedCounter:

    class SynchronizedCounter {
        private int c = 0;
    
        public synchronized void increment() {
            c++;
        }
    
        public synchronized void decrement() {
            c--;
        }
    
        public synchronized int value() {
            return c;
        }
    
    }
    

    For this simple class, synchronization is an acceptable solution. But for a more complicated class, we might want to avoid the liveness impact of unnecessary synchronization. Replacing the int field with an AtomicInteger allows us to prevent thread interference without resorting to synchronization, as in AtomicCounter:

    import java.util.concurrent.atomic.AtomicInteger;
    
    class AtomicCounter {
        private AtomicInteger c = new AtomicInteger(0);
    
        public void increment() {
            c.incrementAndGet();
        }
    
        public void decrement() {
            c.decrementAndGet();
        }
    
        public int value() {
            return c.get();
        }
    
    }
    

    译文:
    java.util.concurrent包中包含了许多Java集合框架。这里有许多通过提供接口容易分类的:

    • BlockingQueue 定义了先进先出的数据结构,在你尝试向满队列中添加元素,或者从空队列中检索的时候会出现阻止或超时。
    • ConcurrentMap是java.util.Map的一个子类,定义了有用的原子操作。这些操作删除或者更换一个键-值对只要键替换或者增加一个键不存在的键-值对。标准实现ConcurrenMap的是ConcurrentHashMap,这是HashMap的并发模式。
    • ConcurrentNavigableMap是ConcurrentMap的一个子接口支持近似匹配。标准实现ConcurrentNavigableMap的是ConcurrentSkipListMap,它是并发模式下的TreeMap。

      所有的这些集合都是避免Memory Consistency Errors通过定义在操作之前实现发生关系的并增加了一个对象添加到集合的后续操作如访问和删除该对象。
    原子变量
      java.util.concurrent.atomic包中定义了支持在一个单变量中支持原子操作的许多类。所有的类都有get和set方法就像Volatile变量的reads和writes方法一样。也就是,set方法发生在相关相关性操作之前伴随着任何子类,get也是一样的。原子性的操作CompareAndSet方法也有内存一致性特性。为了看这个包如何使用,让我们返回Conter类我们原来实现的线程接口如下:

     1 class Counter {
     2     private int c = 0;
     3 
     4     public void increment() {
     5         c++;
     6     }
     7 
     8     public void decrement() {
     9         c--;
    10     }
    11 
    12     public int value() {
    13         return c;
    14     }
    15 
    16 }

      一种使Connter方法更加安全是实现线程接口的时候使它的方法同步,如SynchronizedCounter:

     1 class SynchronizedCounter {
     2     private int c = 0;
     3 
     4     public synchronized void increment() {
     5         c++;
     6     }
     7 
     8     public synchronized void decrement() {
     9         c--;
    10     }
    11 
    12     public synchronized int value() {
    13         return c;
    14     }
    15 
    16 }

      对于这个简单的类,synchronization是一个可以接受的解决方法,但是对于更复杂的类,我们可能想避免Liveness影响不必要的synchronization.替代整数域用原子整数,允许我们阻止线程接口而不是利用synchronization,就像AtomicCounter:

     1 import java.util.concurrent.atomic.AtomicInteger;
     2 
     3 class AtomicCounter {
     4     private AtomicInteger c = new AtomicInteger(0);
     5 
     6     public void increment() {
     7         c.incrementAndGet();
     8     }
     9 
    10     public void decrement() {
    11         c.decrementAndGet();
    12     }
    13 
    14     public int value() {
    15         return c.get();
    16     }
    17 
    18 }
  • 相关阅读:
    为应用程序的选项卡及ActionBar设置样式
    在Flex中定义移动设备应用程序和启动屏幕
    在Flex中用于处理XML对象的E4X 方法
    在移动设备应用程序中嵌入字体
    【2020-01-14】一些不起眼的常态局限
    【2020-01-13】一点一点的,一点一点的
    【2020-01-12】昨天跟老骨干聚了个会
    【2020-01-11】多警惕自己的自圆其说
    【2020-01-10】每天早上一个小时的自我修养
    【2020-01-09】看书就是一种很好的娱乐
  • 原文地址:https://www.cnblogs.com/accipiter/p/3308020.html
Copyright © 2020-2023  润新知