Five implementation methods for converting asynchronous calls to synchronization in Java
The core difference between asynchronous and synchronization
- Synchronous call: The caller blocks and waits for the result to return
- Asynchronous call: The caller returns immediately and gets the results through callbacks/polling, etc.
This article focuses on how to convert asynchronous calls to synchronous blocking mode. Here are five implementation solutions:
Method 1: Use wait/notify + synchronized
Code Example
public class ProducerConsumerExample { private static final int BUFFER_SIZE = 5; private final Object lock = new Object(); private int[] buffer = new int[BUFFER_SIZE]; private int count = 0; // Producer thread public void produce() throws InterruptedException { int value = 0; while (true) { synchronized (lock) { while (count == BUFFER_SIZE) { ("The buffer is full, the producer is waiting..."); (); } buffer[count++] = value++; ("Production Data: " + value + ", Number of buffers: " + count); (); } (1000); } } // Consumer thread public void consume() throws InterruptedException { while (true) { synchronized (lock) { while (count == 0) { ("The buffer is empty, the consumer is waiting..."); (); } int value = buffer[--count]; ("Consumption Data: " + value + ", Number of buffers: " + count); (); } (1500); } } public static void main(String[] args) { ProducerConsumerExample example = new ProducerConsumerExample(); // Start producer and consumer threads new Thread(example::produce).start(); new Thread(example::consume).start(); } }
Key Points
Shared resource protection: ensure thread safety through synchronized(lock)
-
Conditional judgment:
- While loop instead of if prevent false wakeup
- The producer waits when the buffer is full (wait())
- The buffer is empty when the consumer waits (wait())
Collaboration mechanism: wake up the waiting thread through notify() after each operation
-
Method comparison:
- notify(): Wake up a single waiting thread
- notifyAll(): Wake up all waiting threads (suitable for multi-producer scenarios)
Method 2: Use ReentrantLock + Condition
Code Example
import ; import ; public class TestReentrantLock4 { static ReentrantLock lock = new ReentrantLock(); static Condition moneyCondition = (); static Condition ticketCondition = (); static boolean haveMoney = false; static boolean haveTicket = false; public static void main(String[] args) throws InterruptedException { // Farmer 1 (waiting for money) new Thread(() -> { (); try { while (!haveMoney) { ("Farmer 1 is waiting for funds..."); (); } ("Farmer 1 gets the funds and goes home!"); } finally { (); } }, "Farmer1").start(); // Farmer 2 (wait for tickets) new Thread(() -> { (); try { while (!haveTicket) { ("Farmer 2 is waiting for the ticket..."); (); } ("Farmer 2 gets the ticket and goes home!"); } finally { (); } }, "Farmer2").start(); // Main thread simulates the issuance conditions (1000); (); try { haveMoney = true; (); ("Funds have been issued!"); haveTicket = true; (); ("Tickets have been issued!"); } finally { (); } } }
Core features
-
Multi-condition support:
- A lock object can bind multiple Conditions (such as moneyCondition/ticketCondition)
-
Accurate wake-up:
- await(): Release the lock and wait for a specific condition
- signal(): wake up the waiting thread that meets the condition
-
Code structure:
- Must operate between() and finally unlock()
- Conditional judgment Use while loop to prevent false wake-up
Method 3: Future (Callable + ExecutorService)
Code Example
import .*; public class FutureExample { public static void main(String[] args) { ExecutorService executor = (); Future<Integer> future = (() -> { int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; (10); } return sum; }); ("The main thread performs other tasks..."); try { Integer result = (2, ); ("Calculation results: 1+2+...+100 = " + result); } catch (TimeoutException e) { ("Calculation timeout!"); (true); } catch (Exception e) { (); } finally { (); } } }
Key APIs
method | effect |
---|---|
() | Blocking to get results (timeout can be set) |
() | Cancel task execution |
isDone() | Check whether the task is completed |
Execution process
- Submit Callable tasks to thread pool
- The main thread continues to perform other operations
- Call() to block and wait for the result
- Handle possible exceptions
- Finally close the thread pool resource
Method 4: CountDownLatch (multi-threaded synchronization)
Code Example
import ; import ; import ; public class CountDownLatchExample { private static final int RUNNERS = 5; private static final CountDownLatch startSignal = new CountDownLatch(1); private static final CountDownLatch readySignal = new CountDownLatch(RUNNERS); public static void main(String[] args) throws InterruptedException { ExecutorService executor = (RUNNERS); for (int i = 1; i <= RUNNERS; i++) { (() -> { try { ("athlete" + i + "Preparing..."); (300); (); (); ("athlete" + i + "Start!"); ((long)(() * 1000)); ("athlete" + i + "Get the end!"); } catch (InterruptedException e) { (); } }); } ("The referee waits for the athlete to take his seat..."); (); ("\nAll athletes are in place!"); (1); ("The starting gun fires!"); (); (); (5, ); ("\nThe match is over!"); } }
Application scenarios
- Unified execution after multi-threading: if the service starts, wait for all components to be ready
- Concurrent test control: Simulate fixed number of requests to be initiated simultaneously
- Event-driven programming: Wait for multiple preconditions to complete
Method 5: CyclicBarrier (reusable synchronization barrier)
Code Example
import ; import ; public class CyclicBarrierExample { private static final CyclicBarrier barrier = new CyclicBarrier(3, () -> ("\n===== Entering the next stage =====")); public static void main(String[] args) { for (int i = 1; i <= 3; i++) { new Thread(new TeamMember(i)).start(); } } static class TeamMember implements Runnable { private int id; public TeamMember(int id) { = id; } @Override public void run() { try { doWork("Demand Analysis", 1000); (); doWork("Development coding", 1500); (); doWork("Test Deployment", 800); (); } catch (Exception e) { (); } } private void doWork(String phase, int baseTime) throws InterruptedException { int time = baseTime + (int)(() * 500); ("%s Complete %s(%dms)\n", ().getName(), phase, time); (time); } } }
Core features
Comparison items | CountDownLatch | CyclicBarrier |
---|---|---|
Reusability | One-time use | Repeatable trigger |
Thread relationship | The main thread is waiting for the child thread | Child threads are waiting for each other |
Typical scenarios | Execute after thread initialization is completed | Multi-stage task collaboration |
Summary comparison table
method | Applicable scenarios | Core mechanism | Extensibility |
---|---|---|---|
wait/notify | Simple Producer-Consumer Model | Waiting/notifying mechanism for object locks | Low |
ReentrantLock+Condition | Requires multiple condition variables | Fine condition control | middle |
Future | Asynchronous task result acquisition | Task submission and result callback | high |
CountDownLatch | Multi-threaded waiting for a single event | Counter decrement trigger mechanism | middle |
CyclicBarrier | Multi-stage task synchronization | Resettable barrier counting mechanism | high |
Best Practice Recommendations:
- CountDownLatch is preferred for simple synchronization scenarios
- Use Future when the result is returned
- Recommended CyclicBarrier in multiple conditions or multi-stage scenarios
- Avoid using outdated /notifydirect control
The above is the detailed content of five methods in Java to convert asynchronous calls to synchronization. For more information about Java asynchronous calls to synchronization, please pay attention to my other related articles!
Related Articles
Java reflection_Simple examples of changing variables and methods in private
Below, the editor will bring you a simple example of Java reflection_changing variables and methods in private. The editor thinks it is quite good, so I will share it with you now and give you a reference. Let's take a look with the editor2016-06-06SpringBoot implements asynchronous event-driven method
This article mainly introduces SpringBoot's asynchronous event-driven method. The article introduces the example code in detail, which has certain reference learning value for everyone's learning or work. If you need it, please learn with the editor below.2021-06-06Detailed explanation of the difference between deploying jars and wars in Spring Boot
This article mainly introduces the details of the difference between Spring Boot deployment jar and war. The editor thinks it is quite good. I will share it with you now and give you a reference. Let's take a look with the editor2017-09-09Detailed explanation of Spring FactoryLoader mechanism instance
This article mainly introduces a detailed explanation of Spring FactoryLoader mechanism examples. The example code is introduced in this article in detail, which has certain reference value for everyone's learning or work. Friends who need it can refer to it.2020-03-03Analysis of the principle and process of Java Synchronized lock upgrade
This article mainly introduces the principles and processes of Synchronized lock upgrade in Java in detail. The sample code in the article is explained in detail. Interested friends can follow the editor to learn and learn together.2022-08-08Spring Boot Integration Spring Boot Admin Monitoring
This article mainly introduces Spring Boot integrated Spring Boot Admin monitoring. The example code is introduced in this article in detail, which has certain reference learning value for everyone's study or work. Friends who need it, please learn with the editor below.2020-08-08Detailed introduction to easy-rules of Java rules engine
This article mainly introduces the detailed introduction of easy-rules in the Java rule engine. The example code is introduced in this article in detail and has certain reference value. Interested friends can refer to it.2022-01-01A tracking eye code that rotates with the mouse
The tracking eye code that implements the java to follow the mouse2008-10-10Detailed explanation of the tutorial on accessing the html page of Springboot
This article mainly introduces the tutorial on Springboot's html page. This article has introduced you with pictures and texts in a very detailed way. Friends who need it can refer to it.2018-03-03Example of springboot+vue implementing SSE server sending events
This article introduces the use of Spring Boot and Vue to implement server sending events. The example code is introduced in this article in detail, which has certain reference learning value for everyone's learning or work. Friends who need it, please learn with the editor below.2025-01-01