Add AtomicReference to gwt/emul.

Change-Id: Ib3677b5e223a0a128b6f88ef2b436e138b8dcb8b
diff --git a/user/super/com/google/gwt/emul/java/util/concurrent/atomic/AtomicReference.java b/user/super/com/google/gwt/emul/java/util/concurrent/atomic/AtomicReference.java
new file mode 100644
index 0000000..2b494ed
--- /dev/null
+++ b/user/super/com/google/gwt/emul/java/util/concurrent/atomic/AtomicReference.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2019 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package java.util.concurrent.atomic;
+
+/**
+ * GWT emulation of AtomicReference.
+ *
+ * @param <V> The type of object referred to by this reference
+ */
+public class AtomicReference<V> {
+
+  private V value;
+
+  public AtomicReference() {
+  }
+
+  public AtomicReference(V initialValue) {
+    value = initialValue;
+  }
+
+  public final boolean compareAndSet(V expect, V update) {
+    if (value == expect) {
+      value = update;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  public final V get() {
+    return value;
+  }
+
+  public final V getAndSet(V newValue) {
+    V oldValue = value;
+    value = newValue;
+    return oldValue;
+  }
+
+  public final void lazySet(V newValue) {
+    set(newValue);
+  }
+
+  public final void set(V newValue) {
+    value = newValue;
+  }
+
+  public final boolean weakCompareAndSet(V expect, V update) {
+    return compareAndSet(expect, update);
+  }
+
+  @Override
+  public String toString() {
+    return String.valueOf(value);
+  }
+}
diff --git a/user/test/com/google/gwt/emultest/java/util/concurrent/atomic/AtomicReferenceTest.java b/user/test/com/google/gwt/emultest/java/util/concurrent/atomic/AtomicReferenceTest.java
new file mode 100644
index 0000000..6d7e1ca
--- /dev/null
+++ b/user/test/com/google/gwt/emultest/java/util/concurrent/atomic/AtomicReferenceTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.emultest.java.util.concurrent.atomic;
+
+import com.google.gwt.emultest.java.util.EmulTestBase;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * Tests for {@link java.util.concurrent.atomic.AtomicReference} that runs in plain junit and GWT
+ * modes.
+ */
+public class AtomicReferenceTest extends EmulTestBase {
+
+  public void testNoArgConstructor() {
+    AtomicReference<Object> ar = new AtomicReference<>();
+    assertNull(ar.get());
+  }
+
+  public void testWithValueConstructor() {
+    Object object = new Object();
+    AtomicReference<Object> ar = new AtomicReference<>(object);
+    assertEquals(object, ar.get());
+  }
+
+  public void testCompareAndSetPositive() {
+    Object expect = new Object();
+    Object update = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(expect);
+    boolean returnValue = ar.compareAndSet(expect, update);
+
+    assertTrue(returnValue);
+    assertEquals(update, ar.get());
+  }
+
+  public void testCompareAndSetNegative() {
+    Object expect = new Object();
+    Object update = new Object();
+    Object notExpect = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(expect);
+    boolean returnValue = ar.compareAndSet(notExpect, update);
+
+    assertFalse(returnValue);
+    assertEquals(expect, ar.get());
+  }
+
+  public void testGetAndSet() {
+    Object old = new Object();
+    Object update = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(old);
+    Object returnValue = ar.getAndSet(update);
+
+    assertEquals(old, returnValue);
+    assertEquals(update, ar.get());
+  }
+
+  public void testLazySet() {
+    Object old = new Object();
+    Object update = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(old);
+    ar.lazySet(update);
+
+    assertEquals(update, ar.get());
+  }
+
+  public void testSet() {
+    Object old = new Object();
+    Object update = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(old);
+    ar.lazySet(update);
+
+    assertEquals(update, ar.get());
+  }
+
+  public void testWeakCompareAndSetPositive() {
+    Object expect = new Object();
+    Object update = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(expect);
+    boolean returnValue = ar.weakCompareAndSet(expect, update);
+
+    assertTrue(returnValue);
+    assertEquals(update, ar.get());
+  }
+
+  public void testWeakCompareAndSetNegative() {
+    Object expect = new Object();
+    Object update = new Object();
+    Object notExpect = new Object();
+
+    AtomicReference<Object> ar = new AtomicReference<>(expect);
+    boolean returnValue = ar.weakCompareAndSet(notExpect, update);
+
+    assertFalse(returnValue);
+    assertEquals(expect, ar.get());
+  }
+}