240118-JAVA实现多个线程顺序执行的几种方式

147 阅读1分钟

方式1:Thread.join()

thread1.join():等待thread1执行完再继续往下执行。

public static void main(String[] args) throws InterruptedException {
    Thread thread1 = new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"-A");
    }, "Thread-1");
    Thread thread2 = new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"-B");
    }, "Thread-2");
    Thread thread3 = new Thread(()->{
        System.out.println(Thread.currentThread().getName()+"-C");
    }, "Thread-3");

    thread1.start();
    thread1.join();
    thread2.start();
    thread2.join();
    thread3.start();
    thread3.join();
}

输出结果:

Thread-1-A
Thread-2-B
Thread-3-C

方式2:Thread.join()变种

抽取出一个线程类

public class OrderTread extends Thread{
    private Thread beforeThread;
    private String str;

    OrderTread(Thread beforeThread, String str){
        this.beforeThread = beforeThread;
        this.str = str;
    }

    @Override
    public void run() {
        try {
            if (beforeThread != null) {
                beforeThread.join();
            }
            System.out.println(Thread.currentThread().getName() + "-" + str);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        OrderTread thread1 = new OrderTread(null, "A");
        OrderTread thread2 = new OrderTread(thread1, "B");
        OrderTread thread3 = new OrderTread(thread2, "C");

        thread1.start();
        thread2.start();
        thread3.start();
    }

}

输出:

Thread-0-A
Thread-1-B
Thread-2-C

方式3:CountDownLatch

java.util.concurrent.CountDownLatch
实现一个线程(或者多个), 等待另外N个线程完成某个事情之后才能执行。

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

    final CountDownLatch countDownLatch = new CountDownLatch(2);

    System.out.println("开始");

    new Thread(() -> {
        System.out.println(Thread.currentThread().getName() + "-" + "A");
        countDownLatch.countDown();
    }).start();

    new Thread(() -> {
        System.out.println(Thread.currentThread().getName() + "-" + "B");
        countDownLatch.countDown();
    }).start();

    countDownLatch.await();
    System.out.println("结束");
}

输出:

开始
Thread-0-A
Thread-1-B
结束

方式4:线程池实现

单线程池+顺序队列,以此保证顺序执行
executorService.shutdown(),不再接受submit的任务,但队列的任务还会继续执行(还有shutdownNow()、awaitTermination())

public static void main(String[] args) throws InterruptedException {
    ExecutorService executorService = Executors.newSingleThreadExecutor();
    for (int i = 0; i < 3; i++){
        int finalI = i;
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "-" + finalI);
            }
        });
    }
    executorService.shutdown();
}

输出:

pool-1-thread-1-0
pool-1-thread-1-1
pool-1-thread-1-2

方式5:CompletableFuture

1.CompletableFuture.runAsync()配合future1.thenRun()来保证顺序
2.runAsync()+thenRun()不能接受返回值,返回值可以用supplyAsync()+thenApply()
3.从输出结果可见CompletableFuture使用的默认线程池是ForkJoinPool。也支持自定义线程池传入CompletableFuture future1 = CompletableFuture.runAsync(() -> { System.out.println("A"); }, Executors.newCachedThreadPool());

public static void main(String[] args) throws InterruptedException {
    CompletableFuture future1 = CompletableFuture.runAsync(() -> {
        System.out.println(Thread.currentThread().getName() + "-" + "A");
    });
    CompletableFuture future2 = future1.thenRun(()->{
        System.out.println(Thread.currentThread().getName() + "-" + "B");
    });
    future2.thenRun(()->{
        System.out.println(Thread.currentThread().getName() + "-" + "C");
    });
}

输出

ForkJoinPool.commonPool-worker-1-A
ForkJoinPool.commonPool-worker-1-B
main-C

参考文章:

blog.csdn.net/qq_29882585…
juejin.cn/post/697055…