Java Concurrency 简明教程

AtomicReferenceArray Class

java.util.concurrent.atomic.AtomicReferenceArray 类在基础引用数组上提供操作,这些操作可以原子地进行读和写,还包含高级原子操作。AtomicReferenceArray 支持对基础引用数组变量进行原子操作。它有 get 和 set 方法,这些方法的工作方式类似于对 volatile 变量进行读取和写入。也就是说,set 与对同一变量的任何后续 get 具有存在先行关系。原子 compareAndSet 方法也具有这些内存一致性特性。

A java.util.concurrent.atomic.AtomicReferenceArray class provides operations on underlying reference array that can be read and written atomically, and also contains advanced atomic operations. AtomicReferenceArray supports atomic operations on underlying reference array variable. It have get 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.

AtomicReferenceArray Methods

以下是 AtomicReferenceArray 类中可用一些重要方法的列表。

Following is the list of important methods available in the AtomicReferenceArray class.

Sr.No.

Method & Description

1

public boolean compareAndSet(int i, E expect, E update) Atomically sets the element at position i to the given updated value if the current value == the expected value.

2

public E get(int i) Gets the current value at position i.

3

public E getAndSet(int i, E newValue) Atomically sets the element at position i to the given value and returns the old value.

4

public void lazySet(int i, E newValue) Eventually sets the element at position i to the given value.

5

public int length() Returns the length of the array.

6

public void set(int i, E newValue) Sets the element at position i to the given value.

7

public String toString() Returns the String representation of the current values of array.

8

public boolean weakCompareAndSet(int i, E expect, E update) Atomically sets the element at position i to the given updated value if the current value == the expected value.

Example

以下 TestThread 程序展示了在基于线程的环境中,AtomicReferenceArray 变量的用法。

The following TestThread program shows usage of AtomicReferenceArray variable in thread based environment.

import java.util.concurrent.atomic.AtomicReferenceArray;

public class TestThread {
   private static String[] source = new String[10];
   private static AtomicReferenceArray<String> atomicReferenceArray
      = new AtomicReferenceArray<String>(source);

   public static void main(final String[] arguments) throws InterruptedException {

      for (int i = 0; i<atomicReferenceArray.length(); i++) {
         atomicReferenceArray.set(i, "item-2");
      }

      Thread t1 = new Thread(new Increment());
      Thread t2 = new Thread(new Compare());
      t1.start();
      t2.start();

      t1.join();
      t2.join();
   }

   static class Increment implements Runnable {

      public void run() {

         for(int i = 0; i<atomicReferenceArray.length(); i++) {
            String add = atomicReferenceArray.getAndSet(i,"item-"+ (i+1));
            System.out.println("Thread " + Thread.currentThread().getId()
               + ", index " +i + ", value: "+ add);
         }
      }
   }

   static class Compare implements Runnable {

      public void run() {

         for(int i = 0; i<atomicReferenceArray.length(); i++) {
            System.out.println("Thread " + Thread.currentThread().getId()
               + ", index " +i + ", value: "+ atomicReferenceArray.get(i));
            boolean swapped = atomicReferenceArray.compareAndSet(i, "item-2", "updated-item-2");
            System.out.println("Item swapped: " + swapped);

            if(swapped) {
               System.out.println("Thread " + Thread.currentThread().getId()
                  + ", index " +i + ", updated-item-2");
            }
         }
      }
   }
}

这将产生以下结果。

This will produce the following result.

Output

Thread 9, index 0, value: item-2
Thread 10, index 0, value: item-1
Item swapped: false
Thread 10, index 1, value: item-2
Item swapped: true
Thread 9, index 1, value: updated-item-2
Thread 10, index 1, updated-item-2
Thread 10, index 2, value: item-3
Item swapped: false
Thread 10, index 3, value: item-2
Item swapped: true
Thread 10, index 3, updated-item-2
Thread 10, index 4, value: item-2
Item swapped: true
Thread 10, index 4, updated-item-2
Thread 10, index 5, value: item-2
Item swapped: true
Thread 10, index 5, updated-item-2
Thread 10, index 6, value: item-2
Thread 9, index 2, value: item-2
Item swapped: true
Thread 9, index 3, value: updated-item-2
Thread 10, index 6, updated-item-2
Thread 10, index 7, value: item-2
Thread 9, index 4, value: updated-item-2
Item swapped: true
Thread 9, index 5, value: updated-item-2
Thread 10, index 7, updated-item-2
Thread 9, index 6, value: updated-item-2
Thread 10, index 8, value: item-2
Thread 9, index 7, value: updated-item-2
Item swapped: true
Thread 9, index 8, value: updated-item-2
Thread 10, index 8, updated-item-2
Thread 9, index 9, value: item-2
Thread 10, index 9, value: item-10
Item swapped: false