diff --git a/README.md b/README.md
index 109428295..bf763787a 100644
--- a/README.md
+++ b/README.md
@@ -72,6 +72,7 @@ Concurrency patterns are those types of design patterns that deal with the multi
* [Double Checked Locking](#double-checked-locking)
* [Thread Pool](#thread-pool)
* [Async Method Invocation](#async-method-invocation)
+* [Half-Sync/Half-Async](#half-sync-half-async)
### Presentation Tier Patterns
@@ -714,7 +715,22 @@ validation and for building to order
* you want to orchestrate calls to multiple business services
* you want to encapsulate service lookups and service calls
+## Half-Sync/Half-Async [↑](#list-of-design-patterns)
+**Intent:** The Half-Sync/Half-Async pattern decouples synchronous I/O from asynchronous I/O in a system to simplify concurrent programming effort without degrading execution efficiency.
+
+
+**Applicability:** Use Half-Sync/Half-Async pattern when
+* A system possesses following characteristics:
+ * System must perform tasks in response to external events that occur asynchronously, like hardware interrupts in OS
+ * It is inefficient to dedicate separate thread of control to perform synchronous I/O for each external source of event
+ * The higher level tasks in the system can be simplified significantly if I/O is performed synchronously.
+* One or more tasks in a system must run in a single thread of control, while other tasks may benefit from multi-threading.
+
+**Real world examples:**
+* [BSD Unix networking subsystem](http://www.cs.wustl.edu/~schmidt/PDF/PLoP-95.pdf)
+* [Real Time CORBA](http://www.omg.org/news/meetings/workshops/presentations/realtime2001/4-3_Pyarali_thread-pool.pdf)
+* [Android AsyncTask framework](http://developer.android.com/reference/android/os/AsyncTask.html)
# Frequently asked questions
diff --git a/half-sync-half-async/etc/half-sync-half-async.png b/half-sync-half-async/etc/half-sync-half-async.png
new file mode 100644
index 000000000..84658dfde
Binary files /dev/null and b/half-sync-half-async/etc/half-sync-half-async.png differ
diff --git a/half-sync-half-async/etc/half-sync-half-async.ucls b/half-sync-half-async/etc/half-sync-half-async.ucls
new file mode 100644
index 000000000..5b9941872
--- /dev/null
+++ b/half-sync-half-async/etc/half-sync-half-async.ucls
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/half-sync-half-async/pom.xml b/half-sync-half-async/pom.xml
new file mode 100644
index 000000000..edbc2e420
--- /dev/null
+++ b/half-sync-half-async/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+ com.iluwatar
+ java-design-patterns
+ 1.5.0
+
+ half-sync-half-async
+
+
+ junit
+ junit
+ test
+
+
+
diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java
new file mode 100644
index 000000000..77b1988ba
--- /dev/null
+++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/App.java
@@ -0,0 +1,118 @@
+package com.iluwatar.halfsynchalfasync;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * This application demonstrates Half-Sync/Half-Async pattern. Key parts of the pattern are
+ * {@link AsyncTask} and {@link AsynchronousService}.
+ *
+ *
+ * PROBLEM
+ *
+ * A concurrent system have a mixture of short duration, mid duration and long duration tasks.
+ * Mid or long duration tasks should be performed asynchronously to meet quality of service
+ * requirements.
+ *
+ *
INTENT
+ *
+ * The intent of this pattern is to separate the the synchronous and asynchronous processing
+ * in the concurrent application by introducing two intercommunicating layers - one for sync
+ * and one for async. This simplifies the programming without unduly affecting the performance.
+ *
+ *
+ * APPLICABILITY
+ *
+ *
+ * - UNIX network subsystems - In operating systems network operations are carried out
+ * asynchronously with help of hardware level interrupts.
+ * - CORBA - At the asynchronous layer one thread is associated with each socket that is
+ * connected to the client. Thread blocks waiting for CORBA requests from the client. On receiving
+ * request it is inserted in the queuing layer which is then picked up by synchronous layer which
+ * processes the request and sends response back to the client.
+ * - Android AsyncTask framework - Framework provides a way to execute long running blocking calls,
+ * such as downloading a file, in background threads so that the UI thread remains free to respond
+ * to user inputs.
+ *
+ *
+ *
+ * IMPLEMENTATION
+ *
+ * The main method creates an asynchronous service which does not block the main thread while
+ * the task is being performed. The main thread continues its work which is similar to Async Method
+ * Invocation pattern. The difference between them is that there is a queuing layer between Asynchronous
+ * layer and synchronous layer, which allows for different communication patterns between both layers.
+ * Such as Priority Queue can be used as queuing layer to prioritize the way tasks are executed.
+ * Our implementation is just one simple way of implementing this pattern, there are many variants possible
+ * as described in its applications.
+ */
+public class App {
+
+ public static void main(String[] args) {
+ AsynchronousService service = new AsynchronousService(new LinkedBlockingQueue<>());
+ /*
+ * A new task to calculate sum is received but as this is main thread, it should not block.
+ * So it passes it to the asynchronous task layer to compute and proceeds with handling other
+ * incoming requests. This is particularly useful when main thread is waiting on Socket to receive
+ * new incoming requests and does not wait for particular request to be completed before responding
+ * to new request.
+ */
+ service.execute(new ArithmeticSumTask(1000));
+
+ /* New task received, lets pass that to async layer for computation. So both requests will be
+ * executed in parallel.
+ */
+ service.execute(new ArithmeticSumTask(500));
+ service.execute(new ArithmeticSumTask(2000));
+ service.execute(new ArithmeticSumTask(1));
+ }
+
+ static class ArithmeticSumTask implements AsyncTask {
+ private long n;
+
+ public ArithmeticSumTask(long n) {
+ this.n = n;
+ }
+
+ /*
+ * This is the long running task that is performed in background. In our example
+ * the long running task is calculating arithmetic sum with artificial delay.
+ */
+ @Override
+ public Long call() throws Exception {
+ return ap(n);
+ }
+
+ /*
+ * This will be called in context of the main thread where some validations can be
+ * done regarding the inputs. Such as it must be greater than 0. It's a small
+ * computation which can be performed in main thread. If we did validated the input
+ * in background thread then we pay the cost of context switching
+ * which is much more than validating it in main thread.
+ */
+ @Override
+ public void onPreCall() {
+ if (n < 0) {
+ throw new IllegalArgumentException("n is less than 0");
+ }
+ }
+
+ @Override
+ public void onPostCall(Long result) {
+ // Handle the result of computation
+ System.out.println(result);
+ }
+
+ @Override
+ public void onError(Throwable throwable) {
+ throw new IllegalStateException("Should not occur");
+ }
+ }
+
+ private static long ap(long i) {
+ try {
+ Thread.sleep(i);
+ } catch (InterruptedException e) {
+ }
+ return (i) * (i + 1) / 2;
+ }
+}
diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsyncTask.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsyncTask.java
new file mode 100644
index 000000000..8ed7376b6
--- /dev/null
+++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsyncTask.java
@@ -0,0 +1,44 @@
+package com.iluwatar.halfsynchalfasync;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Represents some computation that is performed asynchronously and its result.
+ * The computation is typically done is background threads and the result is posted
+ * back in form of callback. The callback does not implement {@code isComplete}, {@code cancel}
+ * as it is out of scope of this pattern.
+ *
+ * @param type of result
+ */
+public interface AsyncTask extends Callable {
+ /**
+ * Is called in context of caller thread before call to {@link #call()}. Large
+ * tasks should not be performed in this method as it will block the caller thread.
+ * Small tasks such as validations can be performed here so that the performance penalty
+ * of context switching is not incurred in case of invalid requests.
+ */
+ void onPreCall();
+
+ /**
+ * A callback called after the result is successfully computed by {@link #call()}. In our
+ * implementation this method is called in context of background thread but in some variants,
+ * such as Android where only UI thread can change the state of UI widgets, this method is called
+ * in context of UI thread.
+ */
+ void onPostCall(O result);
+
+ /**
+ * A callback called if computing the task resulted in some exception. This method
+ * is called when either of {@link #call()} or {@link #onPreCall()} throw any exception.
+ *
+ * @param throwable error cause
+ */
+ void onError(Throwable throwable);
+
+ /**
+ * This is where the computation of task should reside. This method is called in context
+ * of background thread.
+ */
+ @Override
+ O call() throws Exception;
+}
diff --git a/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java
new file mode 100644
index 000000000..6c36354d0
--- /dev/null
+++ b/half-sync-half-async/src/main/java/com/iluwatar/halfsynchalfasync/AsynchronousService.java
@@ -0,0 +1,75 @@
+package com.iluwatar.halfsynchalfasync;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * This is the asynchronous layer which does not block when a new request arrives. It just passes
+ * the request to the synchronous layer which consists of a queue i.e. a {@link BlockingQueue} and
+ * a pool of threads i.e. {@link ThreadPoolExecutor}. Out of this pool of worker threads one of the
+ * thread picks up the task and executes it synchronously in background and the result is posted back
+ * to the caller via callback.
+ */
+public class AsynchronousService {
+
+ /*
+ * This represents the queuing layer as well as synchronous layer of the pattern. The thread
+ * pool contains worker threads which execute the tasks in blocking/synchronous manner. Long
+ * running tasks should be performed in the background which does not affect the performance of
+ * main thread.
+ */
+ private ExecutorService service;
+
+ /**
+ * Creates an asynchronous service using {@code workQueue} as communication channel between
+ * asynchronous layer and synchronous layer. Different types of queues such as Priority queue,
+ * can be used to control the pattern of communication between the layers.
+ */
+ public AsynchronousService(BlockingQueue workQueue) {
+ service = new ThreadPoolExecutor(10, 10, 10, TimeUnit.SECONDS, workQueue);
+ }
+
+
+ /**
+ * A non-blocking method which performs the task provided in background and returns immediately.
+ *
+ * On successful completion of task the result is posted back using callback method
+ * {@link AsyncTask#onPostCall(Object)}, if task execution is unable to complete normally
+ * due to some exception then the reason for error is posted back using callback method
+ * {@link AsyncTask#onError(Throwable)}.
+ *
+ * NOTE: The results are posted back in the context of background thread in this implementation.
+ */
+ public void execute(final AsyncTask task) {
+ try {
+ // some small tasks such as validation can be performed here.
+ task.onPreCall();
+ } catch (Exception e) {
+ task.onError(e);
+ }
+
+ service.submit(new FutureTask(task) {
+ @Override
+ protected void done() {
+ super.done();
+ try {
+ /* called in context of background thread. There is other variant possible
+ * where result is posted back and sits in the queue of caller thread which
+ * then picks it up for processing. An example of such a system is Android OS,
+ * where the UI elements can only be updated using UI thread. So result must be
+ * posted back in UI thread.
+ */
+ task.onPostCall(get());
+ } catch (InterruptedException e) {
+ // should not occur
+ } catch (ExecutionException e) {
+ task.onError(e.getCause());
+ }
+ }
+ });
+ }
+}
diff --git a/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java
new file mode 100644
index 000000000..54f6ea5a7
--- /dev/null
+++ b/half-sync-half-async/src/test/java/com/iluwatar/halfsynchalfasync/AppTest.java
@@ -0,0 +1,13 @@
+package com.iluwatar.halfsynchalfasync;
+
+import java.util.concurrent.ExecutionException;
+
+import org.junit.Test;
+
+public class AppTest {
+
+ @Test
+ public void test() throws InterruptedException, ExecutionException {
+ App.main(null);
+ }
+}
diff --git a/pom.xml b/pom.xml
index db468a2fb..13105f139 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,7 +71,8 @@
front-controller
repository
async-method-invocation
- business-delegate
+ business-delegate
+ half-sync-half-async