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

The following examples show how to use java.util.concurrent.atomic.AtomicReferenceFieldUpdater#get() . 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: Disposables.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.
 */
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 3
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 4
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 5
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 6
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 7
Source File: Operators.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically terminates the subscription if it is not already a
 * {@link #cancelledSubscription()}, cancelling the subscription and setting the field
 * to the singleton {@link #cancelledSubscription()}.
 *
 * @param <F> the instance type containing the field
 * @param field the field accessor
 * @param instance the parent instance
 * @return true if terminated, false if the subscription was already terminated
 */
public static <F> boolean terminate(AtomicReferenceFieldUpdater<F, Subscription> field,
		F instance) {
	Subscription a = field.get(instance);
	if (a != CancelledSubscription.INSTANCE) {
		a = field.getAndSet(instance, CancelledSubscription.INSTANCE);
		if (a != null && a != CancelledSubscription.INSTANCE) {
			a.cancel();
			return true;
		}
	}
	return false;
}
 
Example 8
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 9
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 10
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 11
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 12
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 13
Source File: OperatorDisposables.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically dispose the {@link Disposable} in the field if not already disposed.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @return true if the {@link Disposable} held by the field was properly disposed
 */
public static <T> boolean dispose(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder) {
	Disposable current = updater.get(holder);
	Disposable d = DISPOSED;
	if (current != d) {
		current = updater.getAndSet(holder, d);
		if (current != d) {
			if (current != null) {
				current.dispose();
			}
			return true;
		}
	}
	return false;
}
 
Example 14
Source File: OperatorDisposables.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.
 */
public 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 15
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 16
Source File: Disposables.java    From reactor-core with Apache License 2.0 5 votes vote down vote up
/**
 * Atomically dispose the {@link Disposable} in the field if not already disposed.
 *
 * @param updater the target field updater
 * @param holder the target instance holding the field
 * @return true if the {@link Disposable} held by the field was properly disposed
 */
static <T> boolean dispose(AtomicReferenceFieldUpdater<T, Disposable> updater, T holder) {
	Disposable current = updater.get(holder);
	Disposable d = DISPOSED;
	if (current != d) {
		current = updater.getAndSet(holder, d);
		if (current != d) {
			if (current != null) {
				current.dispose();
			}
			return true;
		}
	}
	return false;
}
 
Example 17
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 18
Source File: SequenceGroups.java    From Mycat2 with GNU General Public License v3.0 5 votes vote down vote up
/**
 * 原子移除某个指定的sequence
 *
 * @param holder 原子更新的域所属的类对象
 * @param sequenceUpdater 原子更新的域对象
 * @param sequence 要移除的sequence
 * @param <T>
 * @return
 */
public 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 19
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 20
Source File: Exceptions.java    From reactor-core with Apache License 2.0 3 votes vote down vote up
/**
 * Atomic utility to safely mark a volatile throwable reference with a terminal
 * marker.
 *
 * @param field the atomic container
 * @param instance the reference instance
 * @param <T> the instance type
 *
 * @return the previously masked throwable
 */
@Nullable
public static <T> Throwable terminate(AtomicReferenceFieldUpdater<T, Throwable> field,
		T instance) {
	Throwable current = field.get(instance);
	if (current != TERMINATED) {
		current = field.getAndSet(instance, TERMINATED);
	}
	return current;
}