Class FluentSynchronizer
java.lang.Object
com.github.mizool.core.concurrent.FluentSynchronizer
Encapsulates synchronization and wait/notify functionality.
Introduction
By callingdefine(), the calling code sets up a chain of actions that is completed with invoke().
All those actions are performed in one synchronized block using a lock which is private to the
FluentSynchronizer instance.
With its fluent API and encapsulated lock, this class can help increasing both the readability and robustness of
concurrent algorithms. Still, care must be taken to avoid deadlocks, just as if using synchronized blocks
and Object.wait() / Object.notifyAll() directly.
Actions
FluentSynchronizer provides the following actions:
- Invoke custom code
-
run(Runnable)to run arbitrary code -
get(Supplier)to set a value as the chain result which is passed to subsequent actions -
map(Function)to process or transform the current chain result
-
- Sleep until condition is
true-
Whenever the thread receives a wake call, it
checks this condition. If
true, the thread stops sleeping and continues its action chain. Iffalse, it resumes sleeping. - By default, the condition will only be checked when a wake call happens. However, you can also specify the duration of an interval after which the thread should re-check the condition on its own and then stop/resume sleep as explained above.
-
Sleeping is implemented in line with secure coding practices, i.e.
Object.wait()is called inside a loop to ensure liveness and safety (see SEI CERT rule THI03-J for details). -
If the thread is interrupted while waiting,
UncheckedInterruptedExceptionis thrown and the thread's interrupted flag is re-set.
-
Whenever the thread receives a wake call, it
checks this condition. If
- Wake other threads
-
wakeOthers()wakes each sleeping chain (by callingObject.notifyAll()), causing it to check its condition (see above). -
If a chain result was set, the calling
code can decide whether waking takes place by using the
wakeOthersIf(Predicate)action.
-
Example usage
synchronizer.define()
.run(...)
.sleepUntil(...)
.invoke();
synchronizer.define()
.sleepUntil(...)
.run(...)
.wakeOthers()
.invoke();
ResultClass result = synchronizer.define()
.get(...)
.invoke();
synchronizer.define()
.get(...)
.wakeOthersIf(Spline::isReticulated)
.discardResult()
.invoke();
Note on terminology
This class intentionally uses the verbs "sleep" and "wake". If it used "wait" and "notify" instead, its methods would all too easily be confused with methods in java.lang.Object which, if invoked on the objects returned by chained methods, could cause deadlocks.-
Constructor Summary
Constructors -
Method Summary
-
Constructor Details
-
FluentSynchronizer
public FluentSynchronizer()Creates a newFluentSynchronizerinstance.
-
-
Method Details
-
define
-