Java异步编程 1

2020-05-11  本文已影响0人  巴巴11

异步,相比同步执行来说。

早期的异步,可以通过多线程来完成。

例子1

package async;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

/**
 * 早期的异步
 * CountDownLatch实现
 */
public class Main1 {
    final static CountDownLatch latch = new CountDownLatch(2);
    public static void main(String[] args) throws InterruptedException {

        // 同步方法执行
//        syncFunc1();
//        syncFunc2();

        // 异步执行方法
        asyncFunc1();
        asyncFunc2();

        latch.await();
        TimeUnit.SECONDS.sleep(2);
        System.out.println("main thread end...");
    }

    static void syncFunc1() throws InterruptedException {
        System.out.println("执行同步方法1 begin...");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("执行同步方法1 end...");
    }

    static void syncFunc2() throws InterruptedException {
        System.out.println("执行同步方法2 begin...");
        TimeUnit.SECONDS.sleep(2);
        System.out.println("执行同步方法2 end...");
    }

    static void asyncFunc1() throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行同步方法1 begin...");
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行同步方法1 end...");
                latch.countDown();
            }
        }).start();

    }

    static void asyncFunc2() throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行同步方法2 begin...");
                try {
                    TimeUnit.SECONDS.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("执行同步方法2 end...");
                latch.countDown();
            }
        }).start();

    }
}


package async;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

/**
 * 早期的异步
 * CyclicBarrier
 * 效果和Main1一样
 */
public class Main2 {
    final static CyclicBarrier barrier = new CyclicBarrier(2);

    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {

        // 同步方法执行
//        syncFunc1();
//        syncFunc2();

        // 异步执行方法
        asyncFunc1();
        asyncFunc2();

//        barrier.await();
        TimeUnit.SECONDS.sleep(2);
        System.out.println("main thread end...");
    }

    static void syncFunc1() throws InterruptedException {
        System.out.println("执行同步方法1 begin...");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("执行同步方法1 end...");
    }

    static void syncFunc2() throws InterruptedException {
        System.out.println("执行同步方法2 begin...");
        TimeUnit.SECONDS.sleep(2);
        System.out.println("执行同步方法2 end...");
    }

    static void asyncFunc1() throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行同步方法1 begin...");
                try {
                    TimeUnit.SECONDS.sleep(1);
                    System.out.println("执行同步方法1 end...");
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }

    static void asyncFunc2() throws InterruptedException {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("执行同步方法2 begin...");
                try {
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println("执行同步方法2 end...");
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
            }
        }).start();

    }
}

package async;

import java.util.concurrent.*;

/**
 * Main1  Main2是使用多线程,通过线程之间的通信来实现异步的目的
 * 实现异步,可以通过现有的同步组件CountDownLatch,CyclicBarrier,Semaphore
 * 实现同步,则需要锁,synchronized,volatile, lock ,以及通过AQS模板实现的锁 ReentrantLock,ReentrantReadWriteLock等
 * 当然,实现异步可以使用原始Thread手段,thread.join, thread.notify/notifyAll, Thread.sleep, thread.await
 *
 * 异步,等待返回值
 * 这里有个弊端,等待,而且是阻塞的等待
 * 但是如果异步的结果不是后续步骤需要的话,也能接受
 *
 */
public class Main3 {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.out.println("process begin ...");
        ExecutorService pool = Executors.newSingleThreadExecutor();
        Future<String> future = pool.submit(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("step1 begin...");
                TimeUnit.SECONDS.sleep(2);
                return "step1 finished...";
            }
        });
        System.out.println("do something1 ....");
        TimeUnit.SECONDS.sleep(1);
        System.out.println("do something2 ....");
        System.out.println(future.isDone());
        System.out.println(future.get());
        System.out.println("main thread done...");
        pool.shutdown();
    }
}


/**
 * 如果异步的结果,是后续步骤需要的
 * 那么使用CompletableFuture
 *
 * CompletableFuture工具类扩展了Future接口功能,提供了异步回调式的能力
 *
 * supplyAsync(function) 异步执行方法
 * thenAccept(function) 指定异步回调方法
 */
上一篇 下一篇

猜你喜欢

热点阅读