Java Code Examples for java.util.concurrent.atomic.AtomicReferenceFieldUpdater#compareAndSet()

The following examples show how to use java.util.concurrent.atomic.AtomicReferenceFieldUpdater#compareAndSet() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SubscriberUtils.java    From servicetalk with Apache License 2.0 6 votes vote down vote up
/**
 * There are some scenarios where a completion {@link TerminalNotification} can be overridden with an error if
 * errors are produced asynchronously.
 * <p>
 * This method helps set {@link TerminalNotification} atomically providing such an override.
 *
 * @param toSet {@link TerminalNotification} to set.
 * @param overrideComplete Whether exisiting {@link TerminalNotification#complete()} should be overridden with the
 * {@code toSet}.
 * @param terminalNotificationUpdater {@link AtomicReferenceFieldUpdater} to access the current
 * {@link TerminalNotification}.
 * @param flagOwner instance of {@link R} that owns the current {@link TerminalNotification} field referenced by
 * {@code terminalNotificationUpdater}.
 * @param <R> Type of {@code flagOwner}.
 * @return {@code true} if {@code toSet} is updated as the current {@link TerminalNotification}.
 */
public static <R> boolean trySetTerminal(TerminalNotification toSet, boolean overrideComplete,
                 AtomicReferenceFieldUpdater<R, TerminalNotification> terminalNotificationUpdater, R flagOwner) {
    for (;;) {
        TerminalNotification curr = terminalNotificationUpdater.get(flagOwner);
        if (curr != null && !overrideComplete) {
            // Once terminated, terminalNotification will never be set back to null.
            return false;
        } else if (curr == null && terminalNotificationUpdater.compareAndSet(flagOwner, null, toSet)) {
            return true;
        } else if (curr != null && curr.cause() == null) {
            // Override complete
            if (terminalNotificationUpdater.compareAndSet(flagOwner, curr, toSet)) {
                return true;
            }
        } else {
            return false;
        }
    }
}
 
Example 2
Source File: Operators.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
/**
 * A generic utility to atomically replace a subscription or cancel the replacement
 * if current subscription is marked as cancelled (as in {@link #cancelledSubscription()})
 * or was concurrently updated before.
 * <p>
 * The replaced subscription is itself cancelled.
 *
 * @param field The Atomic container
 * @param instance the instance reference
 * @param s the subscription
 * @param <F> the instance type
 *
 * @return true if replaced
 */
public static <F> boolean set(AtomicReferenceFieldUpdater<F, Subscription> field,
		F instance,
		Subscription s) {
	for (; ; ) {
		Subscription a = field.get(instance);
		if (a == CancelledSubscription.INSTANCE) {
			s.cancel();
			return false;
		}
		if (field.compareAndSet(instance, a, s)) {
			if (a != null) {
				a.cancel();
			}
			return true;
		}
	}
}
 
Example 3
Source File: AtomicReferenceFieldUpdaterTest.java    From j2objc with Apache License 2.0 6 votes vote down vote up
/**
 * compareAndSet in one thread enables another waiting for value
 * to succeed
 */
public void testCompareAndSetInMultipleThreads() throws Exception {
    x = one;
    final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
    a = updaterFor("x");

    Thread t = new Thread(new CheckedRunnable() {
        public void realRun() {
            while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
                Thread.yield();
        }});

    t.start();
    assertTrue(a.compareAndSet(this, one, two));
    t.join(LONG_DELAY_MS);
    assertFalse(t.isAlive());
    assertSame(three, a.get(this));
}
 
Example 4
Source File: AtomicReferenceFieldUpdaterTest.java    From openjdk-jdk9 with GNU General Public License v2.0 6 votes vote down vote up
/**
 * compareAndSet in one thread enables another waiting for value
 * to succeed
 */
public void testCompareAndSetInMultipleThreads() throws Exception {
    x = one;
    final AtomicReferenceFieldUpdater<AtomicReferenceFieldUpdaterTest, Integer> a;
    a = updaterFor("x");

    Thread t = new Thread(new CheckedRunnable() {
        public void realRun() {
            while (!a.compareAndSet(AtomicReferenceFieldUpdaterTest.this, two, three))
                Thread.yield();
        }});

    t.start();
    assertTrue(a.compareAndSet(this, one, two));
    t.join(LONG_DELAY_MS);
    assertFalse(t.isAlive());
    assertSame(three, a.get(this));
}
 
Example 5
Source File: OperatorDisposables.java    From reactor-core with Apache License 2.0 6 votes vote down vote up
/**
 * Atomically set the field to a {@link Disposable} and dispose the old content.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @param newValue the new Disposable to set
 * @return true if successful, false if the field contains the {@link #DISPOSED} instance.
 */
public static <T> boolean set(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder, @Nullable Disposable newValue) {
	for (;;) {
		Disposable current = updater.get(holder);
		if (current == DISPOSED) {
			if (newValue != null) {
				newValue.dispose();
			}
			return false;
		}
		if (updater.compareAndSet(holder, current, newValue)) {
			if (current != null) {
				current.dispose();
			}
			return true;
		}
	}
}
 
Example 6
Source File: AtomicTest.java    From jtransc with Apache License 2.0 5 votes vote down vote up
static private void testAtomicReferenceFieldUpdater() {
	System.out.println("AtomicTest.testAtomicReferenceFieldUpdater:");
	AtomicTest obj = new AtomicTest();
	AtomicReferenceFieldUpdater<AtomicTest, Integer> updater = AtomicReferenceFieldUpdater.newUpdater(AtomicTest.class, Integer.class, "value");
	System.out.println(updater.get(obj));
	updater.set(obj, 5);
	System.out.println(updater.get(obj));
	updater.compareAndSet(obj, 4, -4);
	System.out.println(updater.get(obj));
	updater.compareAndSet(obj, 5, -5);
	System.out.println(updater.get(obj));
}
 
Example 7
Source File: Operators.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * A generic utility to atomically replace a subscription or cancel the replacement
 * if the current subscription is marked as already cancelled (as in
 * {@link #cancelledSubscription()}).
 *
 * @param field The Atomic container
 * @param instance the instance reference
 * @param s the subscription
 * @param <F> the instance type
 *
 * @return true if replaced
 */
public static <F> boolean replace(AtomicReferenceFieldUpdater<F, Subscription> field,
		F instance,
		Subscription s) {
	for (; ; ) {
		Subscription a = field.get(instance);
		if (a == CancelledSubscription.INSTANCE) {
			s.cancel();
			return false;
		}
		if (field.compareAndSet(instance, a, s)) {
			return true;
		}
	}
}
 
Example 8
Source File: RingBuffer.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
static <T> boolean removeSequence(final T holder,
		final AtomicReferenceFieldUpdater<T, Sequence[]> sequenceUpdater,
		final Sequence sequence) {
	int numToRemove;
	Sequence[] oldSequences;
	Sequence[] newSequences;

	do {
		oldSequences = sequenceUpdater.get(holder);

		numToRemove = countMatching(oldSequences, sequence);

		if (0 == numToRemove) {
			break;
		}

		final int oldSize = oldSequences.length;
		newSequences = new Sequence[oldSize - numToRemove];

		for (int i = 0, pos = 0; i < oldSize; i++) {
			final Sequence testSequence = oldSequences[i];
			if (sequence != testSequence) {
				newSequences[pos++] = testSequence;
			}
		}
	}
	while (!sequenceUpdater.compareAndSet(holder, oldSequences, newSequences));

	return numToRemove != 0;
}
 
Example 9
Source File: RingBuffer.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
static <T> void addSequence(final T holder,
		final AtomicReferenceFieldUpdater<T, Sequence[]> updater,
		final Sequence sequence) {

	Sequence[] updatedSequences;
	Sequence[] currentSequences;

	do {
		currentSequences = updater.get(holder);
		updatedSequences = copyOf(currentSequences, currentSequences.length + 1);

		updatedSequences[currentSequences.length] = sequence;
	}
	while (!updater.compareAndSet(holder, currentSequences, updatedSequences));
}
 
Example 10
Source File: OperatorDisposables.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically try to set the given {@link Disposable} on the field if it is null or
 * disposes it if the field contains {@link #DISPOSED}.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @param newValue the disposable to set
 * @return true if successful, false otherwise
 */
public static <T> boolean trySet(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder, Disposable newValue) {
	if (!updater.compareAndSet(holder, null, newValue)) {
		if (updater.get(holder) == DISPOSED) {
			newValue.dispose();
		}
		return false;
	}
	return true;
}
 
Example 11
Source File: OperatorDisposables.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically set the field to the given non-null {@link Disposable} and return true,
 * or return false if the field is non-null.
 * If the target field contains the common {@link #DISPOSED} instance, the supplied disposable
 * is disposed. If the field contains other non-null {@link Disposable}, an {@link IllegalStateException}
 * is signalled to the {@code errorCallback}.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @param newValue the new Disposable to set, not null
 * @return true if the operation succeeded, false
 */
public static <T> boolean setOnce(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder, Disposable newValue,
		Consumer<RuntimeException> errorCallback) {
	Objects.requireNonNull(newValue, "newValue is null");
	if (!updater.compareAndSet(holder, null, newValue)) {
		newValue.dispose();
		if (updater.get(holder) != DISPOSED) {
			errorCallback.accept(new IllegalStateException("Disposable already pushed"));
		}
		return false;
	}
	return true;
}
 
Example 12
Source File: Disposables.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically replace the {@link Disposable} in the field with the given new Disposable
 * but do not dispose the old one.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @param newValue the new Disposable to set, null allowed
 * @return true if the operation succeeded, false if the target field contained
 * the common {@link #DISPOSED} instance and the given disposable is not null but is disposed.
 */
static <T> boolean replace(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder, @Nullable Disposable newValue) {
	for (;;) {
		Disposable current = updater.get(holder);
		if (current == DISPOSED) {
			if (newValue != null) {
				newValue.dispose();
			}
			return false;
		}
		if (updater.compareAndSet(holder, current, newValue)) {
			return true;
		}
	}
}
 
Example 13
Source File: Operators.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Sets the given subscription once and returns true if successful, false
 * if the field has a subscription already or has been cancelled.
 * <p>
 * If the field already has a subscription, it is cancelled and the duplicate
 * subscription is reported (see {@link #reportSubscriptionSet()}).
 *
 * @param <F> the instance type containing the field
 * @param field the field accessor
 * @param instance the parent instance
 * @param s the subscription to set once
 * @return true if successful, false if the target was not empty or has been cancelled
 */
public static <F> boolean setOnce(AtomicReferenceFieldUpdater<F, Subscription> field, F instance, Subscription s) {
	Objects.requireNonNull(s, "subscription");
	Subscription a = field.get(instance);
	if (a == CancelledSubscription.INSTANCE) {
		s.cancel();
		return false;
	}
	if (a != null) {
		s.cancel();
		reportSubscriptionSet();
		return false;
	}

	if (field.compareAndSet(instance, null, s)) {
		return true;
	}

	a = field.get(instance);

	if (a == CancelledSubscription.INSTANCE) {
		s.cancel();
		return false;
	}

	s.cancel();
	reportSubscriptionSet();
	return false;
}
 
Example 14
Source File: TestSolutionCompareAndSet.java    From java-katas with MIT License 5 votes vote down vote up
@Test
@Tag("PASSING")
@Order(2)
public void compareAndSetUsingAtomicReferenceFieldUpdater() {

    final AtomicReferenceFieldUpdater<TestSolutionCompareAndSet, Integer> valueUpdater =
            AtomicReferenceFieldUpdater.newUpdater(TestSolutionCompareAndSet.class,
                    Integer.class,
                    "privateVolatile");

    boolean exchanged = valueUpdater.compareAndSet(this, currentValue, newValue);

    assertTrue(exchanged,
            "The value should have been changed to 7, " +
                    "hence exchanged should be true"
            );

    assertEquals(newValue,
            valueUpdater.get(this),
            "The value of the privateVolatile should now be 7");

    exchanged = valueUpdater.compareAndSet(this, 2, 33);

    assertFalse(exchanged,
            "The value should not have changed since the expected value " +
                    "did not match, hence exchanged should be false"
            );

    assertEquals(newValue,
            valueUpdater.get(this),
            "The value of the privateVolatile should still be 7");
}
 
Example 15
Source File: DefaultServiceRequestContext.java    From armeria with Apache License 2.0 5 votes vote down vote up
private void mutateAdditionalResponseHeaders(
        AtomicReferenceFieldUpdater<DefaultServiceRequestContext, HttpHeaders> atomicUpdater,
        Consumer<HttpHeadersBuilder> mutator) {
    for (;;) {
        final HttpHeaders oldValue = atomicUpdater.get(this);
        final HttpHeadersBuilder builder = oldValue.toBuilder();
        mutator.accept(builder);
        final HttpHeaders newValue = builder.build();
        if (atomicUpdater.compareAndSet(this, oldValue, newValue)) {
            return;
        }
    }
}
 
Example 16
Source File: Atomic8Test.java    From openjdk-jdk9 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Object arguments for parameters of type T that are not
 * instances of the class passed to the newUpdater call will
 * result in a ClassCastException being thrown.
 */
public void testFieldUpdaters_ClassCastException() {
    // Use raw types to allow passing wrong object type, provoking CCE
    final AtomicLongFieldUpdater longUpdater = aLongFieldUpdater();
    final AtomicIntegerFieldUpdater intUpdater = anIntFieldUpdater();
    final AtomicReferenceFieldUpdater refUpdater = anIntegerFieldUpdater();
    final Object obj = new Object();
    for (Object x : new Object[]{ new Object(), null }) {
        Runnable[] throwingActions = {
            () -> longUpdater.get(x),
            () -> intUpdater.get(x),
            () -> refUpdater.get(x),

            () -> longUpdater.set(x, 17L),
            () -> intUpdater.set(x, 17),
            () -> refUpdater.set(x, (Integer) 17),

            () -> longUpdater.addAndGet(x, 17L),
            () -> intUpdater.addAndGet(x, 17),

            () -> longUpdater.getAndUpdate(x, y -> y),
            () -> intUpdater.getAndUpdate(x, y -> y),
            () -> refUpdater.getAndUpdate(x, y -> y),

            () -> longUpdater.compareAndSet(x, 17L, 42L),
            () -> intUpdater.compareAndSet(x, 17, 42),
            () -> refUpdater.compareAndSet(x, (Integer) 17, (Integer) 42),
        };
        assertThrows(ClassCastException.class, throwingActions);
    }
}
 
Example 17
Source File: SequenceGroups.java    From sofa-tracer with Apache License 2.0 5 votes vote down vote up
static <T> boolean removeSequence(final T holder,
                                  final AtomicReferenceFieldUpdater<T, Sequence[]> sequenceUpdater,
                                  final Sequence sequence) {
    int numToRemove;
    Sequence[] oldSequences;
    Sequence[] newSequences;

    do {
        oldSequences = sequenceUpdater.get(holder);

        numToRemove = countMatching(oldSequences, sequence);

        if (0 == numToRemove) {
            break;
        }

        final int oldSize = oldSequences.length;
        newSequences = new Sequence[oldSize - numToRemove];

        for (int i = 0, pos = 0; i < oldSize; i++) {
            final Sequence testSequence = oldSequences[i];
            if (sequence != testSequence) {
                newSequences[pos++] = testSequence;
            }
        }
    } while (!sequenceUpdater.compareAndSet(holder, oldSequences, newSequences));

    return numToRemove != 0;
}
 
Example 18
Source File: Exceptions.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Update an empty atomic reference with the given exception, or combine further added
 * exceptions together as suppressed exceptions under a root Throwable with
 * the {@code "Multiple exceptions"} message, if the atomic reference already holds
 * one. This is short-circuited if the reference contains {@link #TERMINATED}.
 * <p>
 * Since composite exceptions and traceback exceptions share the same underlying mechanism
 * of suppressed exceptions, a traceback could be made part of a composite exception.
 * Use {@link #unwrapMultipleExcludingTracebacks(Throwable)} to filter out such elements in
 * a composite if needed.
 *
 * @param <T> the parent instance type
 * @param field the target field updater
 * @param instance the parent instance for the field
 * @param exception the Throwable to add.
 *
 * @return true if added, false if the field contained the {@link #TERMINATED}
 * instance.
 * @see #unwrapMultiple(Throwable)
 */
public static <T> boolean addThrowable(AtomicReferenceFieldUpdater<T, Throwable> field,
		T instance,
		Throwable exception) {
	for (; ; ) {
		Throwable current = field.get(instance);

		if (current == TERMINATED) {
			return false;
		}

		if (current instanceof CompositeException) {
			//this is ok, composite exceptions are never singletons
			current.addSuppressed(exception);
			return true;
		}

		Throwable update;
		if (current == null) {
			update = exception;
		} else {
			update = multiple(current, exception);
		}

		if (field.compareAndSet(instance, current, update)) {
			return true;
		}
	}
}
 
Example 19
Source File: CopyOnWriteAsyncContextMap.java    From servicetalk with Apache License 2.0 5 votes vote down vote up
@Nullable
@Override
public <T> T put(final Key<T> key, final T value,
                 CopyOnWriteAsyncContextMap owner,
                 AtomicReferenceFieldUpdater<CopyOnWriteAsyncContextMap, CopyAsyncContextMap> mapUpdater) {
    return mapUpdater.compareAndSet(owner, this, new OneAsyncContextMap(key, value)) ? null :
            owner.put(key, value);
}
 
Example 20
Source File: TestKataCompareAndSet.java    From java-katas with MIT License 5 votes vote down vote up
@Test
@Tag("PASSING")
@Order(2)
public void compareAndSetUsingAtomicReferenceFieldUpdater() {

    final AtomicReferenceFieldUpdater<TestKataCompareAndSet, Integer> valueUpdater =
            AtomicReferenceFieldUpdater.newUpdater(TestKataCompareAndSet.class,
                    Integer.class,
                    "privateVolatile");

    boolean exchanged = valueUpdater.compareAndSet(this, currentValue, newValue);

    assertTrue(exchanged,
            "The value should have been changed to 7, " +
                    "hence exchanged should be true"
            );

    assertEquals(newValue,
            valueUpdater.get(this),
            "The value of the privateVolatile should now be 7");

    exchanged = valueUpdater.compareAndSet(this, 2, 33);

    assertFalse(exchanged,
            "The value should not have changed since the expected value " +
                    "did not match, hence exchanged should be false"
            );

    assertEquals(newValue,
            valueUpdater.get(this),
            "The value of the privateVolatile should still be 7");
}