Java to achieve asynchronous to synchronous several ways

A common Android asynchronous to synchronous mode is done through Callback + Handler. A common example is that when a subthread requests the network, it calls Callback and sends a message to the main thread through Handler to update the UI. Of course, there are many ways to do this in real development.

Here are some of the ways in which asynchrony can be turned into synchronization in Java.

Note: this is only about the implementation, not the principle, the specific principle please Google.

1, CountDownLatch

CountDownLatch is a synchronization utility class that allows one or more threads to wait until other threads have completed their operations.

There are three sub-tasks Task1, Task2, and Task3, and we want Task1 to be executed after Task2 and Task3 have all been executed. The implementation is as follows:

1. Create a Runnable. The run method prints the current thread, and CountDownLatch#countDown() is called after the thread completes execution.

Private static class CustomRunnable */ private static class CustomRunnable implements Runnable {private CountDownLatch CountDownLatch; private String name; private int delayTime; public CustomRunnable(CountDownLatch countDownLatch, String name, int delayTime) { this.countDownLatch = countDownLatch;  this.name = name; this.delayTime = delayTime; } @Override public voidrun() {
            LogUtils.e(TAG, "Commence execution" + name);
            ThreadUtils.logCurrThreadName(TAG + "" + name);
            try {
                TimeUnit.SECONDS.sleep(delayTime);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            LogUtils.e(TAG, name + "Executed");
            if(countDownLatch ! = null) { countDownLatch.countDown(); }}}Copy the code

CountDownLatch#await() = CountDownLatch#await(); CountDownLatch#await() = CountDownLatch#await(); Create a thread pool and submit tasks Task1, Task2, Task3.

    public void onBtnJavaCountDownLatchClickedTask1 */ countDownLatch = new countDownLatch (2); Runnable Task1 = () -> { LogUtils.e(TAG,"Start executing Task1");
            ThreadUtils.logCurrThreadName(TAG + " Task1"); Try {// Notice that this is the await method, not the await methodwaitMethod, don't ask me why, uncomfortable. countDownLatch.await(); } catch (InterruptedException e) { e.printStackTrace(); } LogUtils.e(TAG,"Task1 completed"); }; / / create a thread pool ExecutorService executors = executors. NewFixedThreadPool (3); // Execute the task. executors.submit(Task1); executors.submit(new CustomRunnable(countDownLatch,"Task2", 3));
        executors.submit(new CustomRunnable(countDownLatch, "Task3", 5)); // shutdown the thread pool executors. Shutdown (); }Copy the code

Output result:

05-24 11:14:32. 632, 2018-2052 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Begin to execute Task1 05-24 11:14:32. 633, 2018-2052 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Task1: Sub Thread, the name - > the pool - 2-05-24 11:14:32 Thread - 1. 634, 2018-2053 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Begin to execute Task2 05-24 11:14:32. 634, 2018-2053 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Task2: Sub Thread, the name - > the pool - 2 - Thread - 05-24 11:14:32. 2, 635, 2018-2054 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Begin to execute Task3 05-24 11:14:32. 635, 2018-2054 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Task3: Sub Thread, the name - > the pool - 2 - Thread - 05-24 11:14:35. 3, 635, 2018-2053 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: 05-24 11:14:37 Task2 has been completed. 636, 2018-2054 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: 05-24 11:14:37 Task3 has been completed. 636, 2018-2052 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Task1 is performedCopy the code

As evidenced by the above log, we submit Task1, which executes first, waits until we reach CountDownLatch#await(), and waits for Task2 and Task3 to complete.

As you can imagine, if there were no CountDownLatch, the Task1, Task2, and Task3 tasks would run independently of each other.

With the addition of CountDownLatch, we can continue to perform Task1 tasks after both Task2 and Task3 have completed.

2, CyclicBarrier

CyclicBarrier is a synchronization helper class that allows a group of threads to wait for each other until a common barrier point is reached.

Create a CyclicBarrier, which takes two parameters. The first parameter indicates that if 10 threads reach the barrier, the second Runnable will execute the run method.

        CyclicBarrier cyclicBarrier = new CyclicBarrier(10, () -> {
            LogUtils.e(TAG, "All missions have been completed.");
            ThreadUtils.logCurrThreadName(TAG + " barrierAction");
        });
Copy the code

② Create 10 tasks and call CyclicBarrier#await() method after each task is finished. ③ Put all 10 tasks into a thread pool for execution.

        List<Runnable> runnables = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            int finalI = i;
            Runnable runnable = () -> {
                LogUtils.e(TAG, "Current is number one" + finalI + "One mission, start executing.");
                ThreadUtils.logCurrThreadName(TAG + "Subtask");
                try {
                    TimeUnit.SECONDS.sleep(finalI);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LogUtils.e(TAG, "Current is number one" + finalI + "One mission. All done."); try { cyclicBarrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); }}; runnables.add(runnable); } ExecutorService executorService = Executors.newCachedThreadPool();for (Runnable r : runnables) {
            executorService.submit(r);
        }
        executorService.shutdown();
Copy the code

Output result:

05-24 11:55:04. 272, 2018-2190 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Is currently the second task, start executing 05-24 11:55:04. 272, 2018-2190 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 3, 272, 2018-2191 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Is currently the third task, start executing 05-24 11:55:04. 272, 2018-2191 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 4, 273, 2018-2188 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is the zeroth task, start executing 05-24 11:55:04. 273, 2018-2188 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3-05-24 11:55:04 Thread - 1. 273, 2018-2188 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is 0 a task, complete 05-24 11:55:04. 273, 2018-2189 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is the first task, start executing 05-24 11:55:04. 273, 2018-2189 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 2, 274, 2018-2192 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is a fourth task, start executing 05-24 11:55:04. 274, 2018-2192 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 5, 275, 2018-2193 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is the fifth task, start executing 05-24 11:55:04. 275, 2018-2193 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 6, 275, 2018-2194 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is sixth task, start executing 05-24 11:55:04. 275, 2018-2194 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 7, 277, 2018-2197 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is ninth task, start executing 05-24 11:55:04. 278, 2018-2197 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 10, 278, 2018-2195 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is 7 a task, start executing 05-24 11:55:04. 278, 2018-2195 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:04. 8, 279, 2018-2196 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Is currently eighth task, start executing 05-24 11:55:04. 279, 2018-2196 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity subtasks: Sub Thread, the name - > the pool - 3 - Thread - 05-24 11:55:05. 9, 274, 2018-2189 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: The current is the first task, complete 05-24 11:55:06. 272, 2018-2190 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Is currently the second task, complete 05-24 11:55:07. 273, 2018-2191 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Is currently the third task, complete 05-24 11:55:08. 276, 2018-2192 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is a fourth task, complete 05-24 11:55:09. 277, 2018-2193 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is the fifth task, complete 05-24 11:55:10. 280, 2018-2194 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is 6 a task, complete 05-24 11:55:11. 282, 2018-2195 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: The current is 7 a task, complete 05-24 11:55:12. 282, 2018-2196 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: Current is eighth task, complete 05-24 11:55:13. 278, 2018-2197 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Current is ninth task, complete 05-24 11:55:13. 278, 2018-2197 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: All tasks are completed the 05-24 11:55:13. 278, 2018-2197 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity barrierAction: sub Thread,name --> pool-3-thread-10Copy the code

As you can see from the output, after the CyclicBarrier#await() method is called in 10 threads, the run method of the Runnable object passed in when our CyclicBarrier object is initialized will be called.

3, FutureTask

There are three implementations:

①Callable + Future + ExecutorService

The first step is to define a Callable object that evaluates in the Call method and returns the result.

    class CustomCallable implements Callable<Integer> {

        @Override
        public Integer call() throws Exception {
            LogUtils.e(TAG, "Compute on child thread");
            ThreadUtils.logCurrThreadName(TAG + " Task start");
            int sum = 0;
            for (int i = 0; i < 20; i++) {
                Thread.sleep(100);
                sum += i;
                ThreadUtils.logCurrThreadName(TAG + " Task sum:" + sum);
            }
            ThreadUtils.logCurrThreadName(TAG + " Task end");
            returnsum; }}Copy the code

The second step is to create a thread pool, submit the custom Callable you just did through the Submit method, and accept the return result through the Future.

Step 3, complete the asynchronous to synchronous operation with the Future#get() method.

    public void onBtnJavaCallableFutureClicked() {
        // Callable + Future + ExecutorService
        ThreadUtils.logCurrThreadName(TAG + " main start");
        ExecutorService executorService = Executors.newCachedThreadPool();
        CustomCallable task = new CustomCallable();
        Future<Integer> result = executorService.submit(task);
        executorService.shutdown();

        ThreadUtils.logCurrThreadName(TAG + " main 111");

        try {
            LogUtils.e(TAG, "Task execution result :" + result.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 10; i++) {
            ThreadUtils.logCurrThreadName(TAG + " main 222:" + i);
        }

        ThreadUtils.logCurrThreadName(TAG + "Main main thread task completed");
    }
Copy the code

Output result:

05-24 12:06:36. 609, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main start: The main Thread, the name - > the main 05-24 12:06:36. 613, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 111: The main Thread, the name - > the main 05-24 12:06:36. 614, 2314-2344 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: The child thread to calculate 05-24 12:06:36. 614, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task start: Sub Thread, the name - > the pool - 2-05-24 12:06:36 Thread - 1. 714, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:0: Sub Thread, the name - > the pool - 2-05-24 12:06:36 Thread - 1. 814, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:1: Sub Thread, the name - > the pool - 2-05-24 12:06:36 Thread - 1. 915, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:3: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 016, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:6: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 116, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:10: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 217, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:15: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 318, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:21: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 418, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:28: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 519, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:36: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 620, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:45: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 620, 2314-2344 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task end: Sub Thread, the name - > the pool - 2-05-24 12:06:37 Thread - 1. 622, 2314-2314 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: Task execution results: 45 05-24 12:06:37. 622, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:0: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:1: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:2: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:3: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:4: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:5: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:6: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:7: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:8: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:9: The main Thread, the name - > the main 05-24 12:06:37. 623, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main Main Thread,name --> mainCopy the code

As you can see, after calling the Future#get method, the main thread is waiting for the result of the child thread’s execution, and when the child thread completes its calculation, it continues to execute the main thread’s code.

②Callable + FutureTask + ExecutorService

Similar to the demo above, except we’ve replaced the Future with FutureTask.

    public void onBtnJavaCallableFutureTaskClicked() {
        // Callable + FutureTask + ExecutorService
        ThreadUtils.logCurrThreadName(TAG + " main start");
        ExecutorService executorService = Executors.newCachedThreadPool();
        CustomCallable task = new CustomCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(task);
        executorService.submit(futureTask);
        executorService.shutdown();

        ThreadUtils.logCurrThreadName(TAG + " main 111");

        try {
            LogUtils.e(TAG, "Task execution result :" + futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 10; i++) {
            ThreadUtils.logCurrThreadName(TAG + " main 222:" + i);
        }

        ThreadUtils.logCurrThreadName(TAG + "Main main thread task completed");
    }
Copy the code

Output result:

05-24 12:10:08. 028, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main start: The main Thread, the name - > the main 05-24 12:10:08. 029, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 111: The main Thread, the name - > the main 05-24 12:10:08. 030, 2314-2362 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: The child thread to calculate 05-24 12:10:08. 030, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task start: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 131, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:0: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 232, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:1: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 333, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:3: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 434, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:6: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 534, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:10: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 635, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:15: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 735, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:21: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 836, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:28: Sub Thread, the name - > the pool - 3-05-24 12:10:08 Thread - 1. 937, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:36: Sub Thread, the name - > the pool - 3-05-24 12:10:09 Thread - 1. 038, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:45: Sub Thread, the name - > the pool - 3-05-24 12:10:09 Thread - 1. 038, 2314-2362 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task end: Sub Thread, the name - > the pool - 3-05-24 12:10:09 Thread - 1. 038, 2314-2314 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: Task execution results: 45 05-24 12:10:09. 038, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:0: The main Thread, the name - > the main 05-24 12:10:09. 038, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:1: The main Thread, the name - > the main 05-24 12:10:09. 038, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:2: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:3: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:4: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:5: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:6: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:7: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:8: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:9: The main Thread, the name - > the main 05-24 12:10:09. 039, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main Main Thread,name --> mainCopy the code

As you can see, the output is consistent with the previous example.

③Callable + FutureTask + Thread

Here we replace the Thread pool in the above example with Thread, all else unchanged.

    public void onViewClicked() {
        // Callable + FutureTask + Thread
        ThreadUtils.logCurrThreadName(TAG + " main start");
        CustomCallable task = new CustomCallable();
        FutureTask<Integer> futureTask = new FutureTask<>(task);
        Thread thread = new Thread(futureTask);
        thread.start();

        ThreadUtils.logCurrThreadName(TAG + " main 111");

        try {
            LogUtils.e(TAG, "Task execution result :" + futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        for (int i = 0; i < 10; i++) {
            ThreadUtils.logCurrThreadName(TAG + " main 222:" + i);
        }

        ThreadUtils.logCurrThreadName(TAG + "Main main thread task completed");
    }
Copy the code

Output result:

05-24 12:12:08. 493, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main start: The main Thread, the name - > the main 05-24 12:12:08. 495, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 111: The main Thread, the name - > the main 05-24 12:12:08. 496, 2314-2377 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: The child thread to calculate 05-24 12:12:08. 496, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task start: Sub Thread, the name - > the Thread - 215-05-24 12:12:08. 596, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:0: Sub Thread, the name - > the Thread - 215-05-24 12:12:08. 698, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:1: Sub Thread, the name - > the Thread - 215-05-24 12:12:08. 798, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:3: Sub Thread, the name - > the Thread - 215-05-24 12:12:08. 899, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:6: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 000, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:10: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 100, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:15: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 202, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:21: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 303, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:28: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 404, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:36: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 506, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task sum:45: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 507, 2314-2377 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity Task end: Sub Thread, the name - > the Thread - 215-05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/FutureTaskActivity: Task execution results: 45 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:0: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:1: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:2: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:3: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:4: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:5: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:6: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:7: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:8: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main 222:9: The main Thread, the name - > the main 05-24 12:12:09. 507, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: FutureTaskActivity main Main Thread,name --> mainCopy the code

The output is the same as above.

4, rxjava

RxJava is particularly powerful at handling asynchronous tasks, as illustrated by two examples.

Map – Allows asynchronous tasks to be executed sequentially

First, let’s use an example where several asynchronous tasks are executed in sequence, with the next task starting depending on the results of the previous task.

Here is an example of a direct login after registration.

The general process is as follows:

Registration request --> Registration Response --> Login request --> Login ResponseCopy the code
① First create four beans to simulate data transformation. They are registration request Bean, registration request response Bean, login request Bean, login request corresponding Bean.

The following is part of the code to register the request Bean, with the corresponding getter/setter and toString methods omitted.

public class RegisterReqBean {
    private String name;
    private String phone;
    private String pwd;

    public RegisterReqBean(String name, String phone, String pwd) {
        this.name = name;
        this.phone = phone;
        this.pwd = pwd; }... }Copy the code

Register the request corresponding Bean:

public class RegisterRespBean {
    private String name;
    private String pwd; private String msg; . }Copy the code

Login request Bean:

public class LoginReqBean {
    private String name;
    private String pwd; private String msg; . }Copy the code

Login request response Bean:

public class LoginRespBean {
    private String name;
    private String pwd; private String msg; . }Copy the code
(2) Create a corresponding Observable and prepare materials for data conversion.
        RegisterReqBean registerReqBean = new RegisterReqBean("The cat mewed."."13333333333"."123456");
        Observable registerRequest = Observable.create(new ObservableOnSubscribe<RegisterReqBean>() {
            @Override
            public void subscribe(ObservableEmitter<RegisterReqBean> emitter) throws Exception {
                LogUtils.e(TAG, "RegisterReqBean :" + registerReqBean);
                ThreadUtils.logCurrThreadName(TAG + "Registration request successful");
                emitter.onNext(registerReqBean);
                LogUtils.e(TAG, "Send registration request");
                emitter.onComplete();
                LogUtils.e(TAG, "Sending registration request completed"); }}); // Simulate the registration response. Convert the RegisterReqBean to RegisterRespBean. Function mockRegisterResp = new Function<RegisterReqBean, RegisterRespBean>() { @Override public RegisterRespBean apply(RegisterReqBean registerReqBean) throws Exception { RegisterRespBean registerRespBean = new RegisterRespBean(registerReqBean.getName(), registerReqBean.getPwd(),"Congratulations on your registration");
                LogUtils.e(TAG, Register response registerRespBean:+ registerRespBean); TimeUnit.SECONDS.sleep(5); / / simulation network latency ThreadUtils. LogCurrThreadName (TAG +"Registration response successful");
                returnregisterRespBean; }}; // Simulate a login request. Convert RegisterRespBean to LoginReqBean. Function mockLoginReq = new Function<RegisterRespBean, LoginReqBean>() { @Override public LoginReqBean apply(RegisterRespBean registerRespBean) throws Exception { LoginReqBean  loginReqBean = new LoginReqBean(registerRespBean.getName() +"I want to log in.", registerRespBean.getPwd());
                LogUtils.e(TAG, "LoginReqBean :" + loginReqBean);
                ThreadUtils.logCurrThreadName(TAG + "Login request successful");
                returnloginReqBean; }}; // Simulate the login response. Convert LoginReqBean to LoginRespBean. Function mockLoginResp = new Function<LoginReqBean, LoginRespBean>() { @Override public LoginRespBean apply(LoginReqBean loginReqBean) throws Exception { LoginRespBean loginRespBean = new LoginRespBean(loginReqBean.getName(), loginReqBean.getPwd(),"Congratulations on your login.");
                LogUtils.e(TAG, "Login response loginRespBean:+ loginRespBean); TimeUnit.SECONDS.sleep(5); / / simulation network latency ThreadUtils. LogCurrThreadName (TAG +"Login response successful");
                returnloginRespBean; }}; // Simulate the acceptance of the logon response. Observer<LoginRespBean> resultObserver = new Observer<LoginRespBean>() { @Override public void onSubscribe(Disposable d)  { LogUtils.e(TAG,"onSubscribe");
            }

            @Override
            public void onNext(LoginRespBean loginRespBean) {
                LogUtils.e(TAG, "OnNext login successful, you can update UI. loginRespBean:" + loginRespBean);
                ThreadUtils.logCurrThreadName(TAG + "");
            }

            @Override
            public void onError(Throwable e) {
                LogUtils.e(TAG, "onError e:" + e.getMessage());
            }

            @Override
            public void onComplete() {
                LogUtils.e(TAG, "onComplete"); }};Copy the code
③ Use the map operator to convert
        registerRequest.subscribeOn(Schedulers.io())
                .observeOn(Schedulers.newThread())
                .map(mockRegisterResp)
                .observeOn(Schedulers.io())
                .map(mockLoginReq)
                .observeOn(Schedulers.newThread())
                .map(mockLoginResp)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(resultObserver);
Copy the code

Final output:

05-24 13:22:17. 823, 2314-2314 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: OnSubscribe 05-24 13:22:17. 826, 2314-2619 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: The registration request registerReqBean: registerReqBean {name ='Cat got a mew', phone='13333333333'.pwd='123456'} 05-24 13:22:17. 826, 2314-2619 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity registration request is successful: Sub Thread, the name - > 05 RxCachedThreadScheduler - 1-24 13:22:17. 827, 2314-2619 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: send register request 05-24 13:22:17. 827, 2314-2619 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Send a registration request complete 05-24 13:22:17. 830, 2314-2620 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: Registered response registerRespBean: registerRespBean {name ='Cat got a mew'.pwd='123456', msg='Congratulations on your registration'} 05-24 13:22:22. 833, 2314-2620 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity registered in response to success: Sub Thread, the name - > 05 RxNewThreadScheduler - 1-24 13:22:22. 835, 2314-2622 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: login request loginReqBean: loginReqBean {name ='The cat mewed and I want to log in.'.pwd='123456'} 05-24 13:22:22. 835, 2314-2622 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity login request is successful: Sub Thread, the name - > RxCachedThreadScheduler - 05-24 13:22:22. 2, 836, 2314-2623 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: login response loginRespBean: loginRespBean {name ='The cat mewed and I want to log in.'.pwd='123456', msg='Congratulations on your login'} 05-24 13:22:27. 838, 2314-2623 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity login successful response: Sub Thread, the name - > RxNewThreadScheduler - 05-24 13:22:27. 2, 838, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: onNext Login successful, you can update the UI. loginRespBean:LoginRespBean{name='The cat mewed and I want to log in.'.pwd='123456', msg='Congratulations on your login'} 05-24 13:22:27. 838, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity: The main Thread, the name - > the main 05-24 13:22:27. 838, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: the onCompleteCopy the code
Merge – Target tasks are executed after multiple asynchronous tasks are executed

Wait for multiple tasks to complete before executing the target task, in no guaranteed order.

    public void onBtnJavaRxjavaMergeClicked() {** ** wait for multiple tasks to complete before executing, Does not guarantee order * / observables o1 = observables. Create ((ObservableOnSubscribe < String >) e - > {ThreadUtils. LogCurrThreadName (TAG +" Observable1");
            TimeUnit.SECONDS.sleep(5);
            e.onNext("The first Observable");
            e.onComplete();
        }).subscribeOn(Schedulers.newThread());

        Observable o2 = Observable.create((ObservableOnSubscribe<String>) e -> {
            ThreadUtils.logCurrThreadName(TAG + " Observable2");
            TimeUnit.SECONDS.sleep(3);
            e.onNext("Second Observable");
            e.onComplete();
        }).subscribeOn(Schedulers.newThread());

        Observable o3 = Observable.create((ObservableOnSubscribe<String>) e -> {
            ThreadUtils.logCurrThreadName(TAG + " Observable3");
            TimeUnit.SECONDS.sleep(1);
            e.onNext("Third Observable"); e.onComplete(); }).subscribeOn(Schedulers.newThread()); /** * The subscriber's onComplete method will not be called until all three tasks have sent the onComplete event. */ Observable.merge(o1, o2, o3) .observeOn(AndroidSchedulers.mainThread()) .subscribe(newObserver() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        LogUtils.e(TAG, "onSubscribe");
                    }

                    @Override
                    public void onNext(Object o) {
                        LogUtils.e(TAG, "onNext: " + o);
                        ThreadUtils.logCurrThreadName(TAG + " onNext");
                    }

                    @Override
                    public void onError(Throwable e) {
                        LogUtils.e(TAG, "onError");
                    }

                    @Override
                    public void onComplete() {
                        LogUtils.e(TAG, "onComplete"); }}); }Copy the code

Output result:

05-24 13:26:59. 176, 2314-2314 / com. Tiny. The demo. Firstlinecode E/AsyncToSyncActivity: OnSubscribe 05-24 13:26:59. 179, 2314-2644 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Observable1: Sub Thread, the name - > RxNewThreadScheduler - 05-24 13:26:59. 3, 181, 2314-2645 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Observable2: Sub Thread, the name - > RxNewThreadScheduler - 05-24 13:26:59. 4, 181, 2314-2646 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity Observable3: Sub Thread, the name - > RxNewThreadScheduler - 05-24 13:27:00. 5, 183, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: onNext: the third observables 05-24 13:27:00. 183, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity onNext: The main Thread, the name - > the main 05-24 13:27:02. 183, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: onNext: The second observables 05-24 13:27:02. 184, 2314-2314 / com. Tiny. Demo. Firstlinecode E/tiny_module: AsyncToSyncActivity onNext: The main Thread, the name - > the main 05-24 13:27:04. 180, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: onNext: First observables 05-24 13:27:04. 181, 2314-2314 / com. Tiny. The demo. Firstlinecode E/tiny_module: AsyncToSyncActivity onNext: The main Thread, the name - > the main 05-24 13:27:04. 181, 2314-2314 / com. Tiny. Demo. Firstlinecode E/AsyncToSyncActivity: the onCompleteCopy the code

The Observer onComplete method is called when all three Observables send onComplete events.

reference

CountDownLatch

FutureTask

Java CyclicBarrier in a nutshell