Files
java-design-patterns/half-sync-half-async/README.md
T
Ilkka Seppälä 6cd2d0353a docs: Content SEO updates (#2990)
* update yaml frontmatter format

* update abstract document

* update abstract factory

* use the new pattern template

* acyclic visitor seo

* adapter seo

* ambassador seo

* acl seo

* aaa seo

* async method invocation seo

* balking seo

* bridge seo

* builder seo

* business delegate and bytecode seo

* caching seo

* callback seo

* chain seo

* update headings

* circuit breaker seo

* client session + collecting parameter seo

* collection pipeline seo

* combinator SEO

* command seo

* cqrs seo

* commander seo

* component seo

* composite seo

* composite entity seo

* composite view seo

* context object seo

* converter seo

* crtp seo

* currying seo

* dao seo

* data bus seo

* data locality seo

* data mapper seo

* dto seo

* decorator seo

* delegation seo

* di seo

* dirty flag seo

* domain model seo

* double buffer seo

* double checked locking seo

* double dispatch seo

* dynamic proxy seo

* event aggregator seo

* event-based asynchronous seo

* eda seo

* event queue seo

* event sourcing seo

* execute around seo

* extension objects seo

* facade seo

* factory seo

* factory kit seo

* factory method seo

* fanout/fanin seo

* feature toggle seo

* filterer seo

* fluent interface seo

* flux seo

* flyweight seo

* front controller seo

* function composition seo

* game loop seo

* gateway seo

* guarded suspension seo

* half-sync/half-async seo

* health check seo

* hexagonal seo

* identity map seo

* intercepting filter seo

* interpreter seo

* iterator seo

* layers seo

* lazy loading seo

* leader election seo

* leader/followers seo

* lockable object seo

* rename and add seo for marker interface

* master-worker seo

* mediator seo

* memento seo

* metadata mapping seo

* microservice aggregator seo

* api gw seo

* microservices log aggregration seo

* mvc seo

* mvi seo

* mvp seo

* mvvm seo

* monad seo

* monitor seo

* monostate seo

* multiton seo

* mute idiom seo

* naked objects & notification seo

* null object seo

* object mother seo

* object pool seo

* observer seo

* optimistic locking seo

* page controller seo

* page object seo

* parameter object seo

* partial response seo

* pipeline seo

* poison pill seo

* presentation model seo

* private class data seo

* producer-consumer seo

* promise seo

* property seo

* prototype seo

* proxy seo

* queue-based load leveling seo

* reactor seo

* registry seo

* repository seo

* RAII seo

* retry seo

* role object seo

* saga seo

* separated interface seo

* serialized entity seo

* serialized lob seo

* servant seo

* server session seo

* service layer seo

* service locator seo

* service to worker seo

* sharding seo

* single table inheritance seo

* singleton seo

* spatial partition seo

* special case seo

* specification seo

* state seo

* step builder seo

* strangler seo

* strategy seo

* subclass sandbox seo

* table module seo

* template method seo

* throttling seo

* tolerant reader seo

* trampoline seo

* transaction script seo

* twin seo

* type object seo

* unit of work seo

* update method seo

* value object seo

* version number seo

* virtual proxy seo

* visitor seo

* seo enhancements

* seo improvements

* SEO enhancements

* SEO improvements

* SEO additions

* SEO improvements

* more SEO improvements

* rename hexagonal + SEO improvements

* SEO improvements

* more SEO stuff

* SEO improvements

* SEO optimizations

* SEO enhancements

* enchance SEO

* improve SEO

* SEO improvements

* update headers
2024-06-08 19:54:44 +03:00

7.8 KiB

title, shortTitle, description, category, language, tag
title shortTitle description category language tag
Half-Sync/Half-Async Pattern in Java: Enhancing System Performance with Dual Processing Half-Sync/Half-Async Learn how the Half-Sync/Half-Async design pattern in Java improves concurrency and system efficiency by decoupling asynchronous and synchronous processing. Explore real-world examples, programmatic implementations, and key use cases. Concurrency en
Asynchronous
Decoupling
Synchronization
Thread management

Also known as

  • Async-Sync Bridge
  • Half-Synchronous/Half-Asynchronous

Intent of Half-Sync/Half-Async Design Pattern

The Half-Sync/Half-Async pattern in Java aims to decouple asynchronous and synchronous processing in concurrent systems, enhancing efficiency and performance. This pattern is particularly useful for managing complex concurrent operations in software systems.

Detailed Explanation of Half-Sync/Half-Async Pattern with Real-World Examples

Real-world example

Imagine a busy restaurant kitchen where order taking is asynchronous, allowing waiters to keep working while chefs cook each dish synchronously. Similarly, the Half-Sync/Half-Async pattern handles multiple asynchronous tasks and synchronous processing in Java applications efficiently. Meanwhile, the cooking (synchronous part) follows a specific sequence and requires waiting for each dish to be prepared before starting the next. This setup enables the restaurant to handle multiple customer orders efficiently, while ensuring each dish is cooked with the required attention and timing, much like the Half-Sync/Half-Async pattern manages asynchronous tasks and synchronous processing in software systems.

In plain words

The Half-Sync/Half-Async pattern separates operations into asynchronous tasks that handle events without waiting, and synchronous tasks that process these events in an orderly and blocking manner.

Wikipedia says

The Half-Sync/Half-Async design pattern is used to solve situations where one part of the application runs synchronously while another runs asynchronously, and the two modules need to communicate with each other.

Programmatic Example of Half-Sync/Half-Async Pattern in Java

The Half-Sync/Half-Async design pattern is a concurrency pattern that separates synchronous and asynchronous processing in a system, simplifying the programming model without affecting performance. It's particularly useful in scenarios where you have a mix of short, mid, and long duration tasks.

In the provided Java implementation, we can see an example of the Half-Sync/Half-Async pattern in the App, AsynchronousService, and ArithmeticSumTask classes.

The App class is the entry point of the application. It creates an instance of AsynchronousService and uses it to handle various tasks asynchronously.

public class App {

  public static void main(String[] args) {
    var service = new AsynchronousService(new LinkedBlockingQueue<>());
    service.execute(new ArithmeticSumTask(1000));
    service.execute(new ArithmeticSumTask(500));
    service.execute(new ArithmeticSumTask(2000));
    service.execute(new ArithmeticSumTask(1));
    service.close();
  }
}

The AsynchronousService class is the asynchronous part of the system. It manages a queue of tasks and processes them in a separate thread.

public class AsynchronousService {
  // Implementation details...
}

The ArithmeticSumTask class represents a task that can be processed asynchronously. It implements the AsyncTask interface, which defines methods for pre-processing, post-processing, and error handling.

static class ArithmeticSumTask implements AsyncTask<Long> {
  private final long numberOfElements;

  public ArithmeticSumTask(long numberOfElements) {
    this.numberOfElements = numberOfElements;
  }

  @Override
  public Long call() throws Exception {
    return ap(numberOfElements);
  }

  @Override
  public void onPreCall() {
    if (numberOfElements < 0) {
      throw new IllegalArgumentException("n is less than 0");
    }
  }

  @Override
  public void onPostCall(Long result) {
    LOGGER.info(result.toString());
  }

  @Override
  public void onError(Throwable throwable) {
    throw new IllegalStateException("Should not occur");
  }
}

This is the main function in the App class.

public static void main(String[] args) {
    
    var service = new AsynchronousService(new LinkedBlockingQueue<>());

    service.execute(new ArithmeticSumTask(1000));

    service.execute(new ArithmeticSumTask(500));
    service.execute(new ArithmeticSumTask(2000));
    service.execute(new ArithmeticSumTask(1));

    service.close();
}

In this example, the App class enqueues tasks to the AsynchronousService, which processes them asynchronously. The ArithmeticSumTask class defines the task to be processed, including pre-processing, the actual processing, and post-processing steps.

Running the code produces:

10:56:33.922 [pool-1-thread-4] INFO com.iluwatar.halfsynchalfasync.App -- 1
10:56:34.425 [pool-1-thread-2] INFO com.iluwatar.halfsynchalfasync.App -- 125250
10:56:34.925 [pool-1-thread-1] INFO com.iluwatar.halfsynchalfasync.App -- 500500
10:56:35.925 [pool-1-thread-3] INFO com.iluwatar.halfsynchalfasync.App -- 2001000

This is a basic example of the Half-Sync/Half-Async pattern, where tasks are enqueued and processed asynchronously, while the main thread continues to handle other tasks.

When to Use the Half-Sync/Half-Async Pattern in Java

Use the Half-Sync/Half-Async pattern in scenarios where:

  • High performance and efficient concurrency are crucial, such as in Java's standard libraries and network servers managing concurrent connections.
  • The system needs to effectively utilize multicore architectures to balance tasks between asynchronous and synchronous processing.
  • Decoupling of asynchronous tasks from synchronous processing is necessary to simplify the design and implementation.

Real-World Applications of Half-Sync/Half-Async Pattern in Java

  • The Half-Sync/Half-Async pattern is utilized in various frameworks and systems, including BSD Unix networking, Real-Time CORBA, and Android's AsyncTask framework.
  • Java's standard libraries utilize this pattern with thread pools and execution queues in the concurrency utilities (e.g., java.util.concurrent).
  • Network servers handling concurrent connections where IO operations are handled asynchronously and processing of requests is done synchronously.

Benefits and Trade-offs of Half-Sync/Half-Async Pattern

Benefits:

  • This pattern improves system responsiveness and throughput by isolating blocking operations from non-blocking ones, making it a valuable design pattern in Java concurrency.
  • Simplifies programming model by isolating asynchronous and synchronous processing layers.

Trade-offs:

  • Adds complexity in managing two different processing modes.
  • Requires careful design to avoid bottlenecks between the synchronous and asynchronous parts.
  • Leader/Followers: Both patterns manage thread assignments and concurrency, but Leader/Followers uses a single thread to handle all I/O events, dispatching work to others.
  • Producer/Consumer: Can be integrated with Half-Sync/Half-Async to manage work queues between the async and sync parts.
  • Reactor: Often used with Half-Sync/Half-Async to handle multiple service requests delivered to a service handler without blocking the handler.

References and Credits