| /* |
| * Copyright (c) 2008-2012 Eike Stepper (Berlin, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Simon McDuff - initial API and implementation |
| * Eike Stepper - maintenance |
| */ |
| package org.eclipse.net4j.util.concurrent; |
| |
| /** |
| * Allow synchronization between many threads for a specific value. |
| * |
| * <pre> |
| * MainThread cv.set(1); |
| * Thread1 cv.acquire(3); |
| * Thread2 cv.acquire(4); |
| * Thread3 cv.acquire(100); |
| * Thread4 cv.acquire(new Object() |
| * { |
| * public boolean equals(Object other) |
| * { |
| * return other.equals(2) || other.equals(3); |
| * } |
| * }); |
| * Thread5 cv.acquire(1); |
| * ... |
| * // Thread 1,2,3 and 4 are blocked |
| * // Thread 5 isn't blocked. |
| * |
| * MainThread cv.set(3); |
| * |
| * // Thread 1 and 4 are unblocked. |
| * // Thread 2 and 3 are still blocked. |
| * </pre> |
| * |
| * @author Simon McDuff |
| * @since 2.0 |
| */ |
| public final class ConcurrentValue<T> |
| { |
| private Object notifier = new Notifier(); |
| |
| private T value; |
| |
| public ConcurrentValue(T value) |
| { |
| this.value = value; |
| } |
| |
| public T get() |
| { |
| return value; |
| } |
| |
| /** |
| * Specify the new value. |
| */ |
| public void set(T newValue) |
| { |
| synchronized (notifier) |
| { |
| value = newValue; |
| notifier.notifyAll(); |
| } |
| } |
| |
| /** |
| * Reevaluate the condition. It is only useful if a thread is blocked at {@link #acquire(Object)} and the parameter |
| * passed changed. {@link #acquire(Object)} generates a reevaluation automatically. |
| */ |
| public void reevaluate() |
| { |
| synchronized (notifier) |
| { |
| notifier.notifyAll(); |
| } |
| } |
| |
| /** |
| * Blocking call. |
| * <p> |
| * Return when value accept is equal to {@link #get()}. |
| */ |
| public void acquire(Object accept) throws InterruptedException |
| { |
| if (accept == null) |
| { |
| throw new IllegalArgumentException("accept == null"); //$NON-NLS-1$ |
| } |
| |
| synchronized (notifier) |
| { |
| while (!accept.equals(value)) |
| { |
| notifier.wait(); |
| } |
| } |
| } |
| |
| /** |
| * @author Eike Stepper |
| */ |
| private static final class Notifier extends Object |
| { |
| } |
| } |