Java—线程按顺序执行

1.第一种方法:Thread.join()

    public static void main(String[] args) {
        final Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("t1");
            }
        });
        final Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    t1.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t2");
            }
        });
        Thread t3 = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    t2.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("t3");
            }
        });
        t3.start();
        t2.start();
        t1.start();
    }

2.第二种方法:线程池

    public static void main(String[] args) {
        final Thread t1 = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("t1");
            }
        });
        final Thread t2 = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("t2");
            }
        });
        Thread t3 = new Thread(new Runnable() {

            @Override
            public void run() {
                System.out.println("t3");
            }
        });

        ExecutorService executorService = Executors.newSingleThreadExecutor();
        executorService.submit(t1);
        executorService.submit(t2);
        executorService.submit(t3);
        executorService.shutdown();
    }


多线程编程中,保证线程顺序执行是常见的需求,尤其是在任务之间存在依赖关系时。以下介绍几种实现多线程顺序执行的方法。 ### 1. 使用 `Thread.join()` 方法 `Thread.join()` 方法可以确保当前线程执行完成后才继续执行其他线程。通过在主线程中依次调用各个线程的 `join()` 方法,可以实现线程顺序执行。 ```java Thread thread1 = new Thread(() -> { // 执行线程1的任务 }); Thread thread2 = new Thread(() -> { // 执行线程2的任务 }); Thread thread3 = new Thread(() -> { // 执行线程3的任务 }); thread1.start(); thread1.join(); // 等待线程1完成 thread2.start(); thread2.join(); // 等待线程2完成 thread3.start(); thread3.join(); // 等待线程3完成 ``` ### 2. 使用信号量(Semaphore)与 `volatile` 关键字 通过共享变量和 `volatile` 关键字,可以实现线程之间的通信。线程会不断检查共享变量的状态,以决定是否执行任务。 ```java static volatile int ticket = 1; public static void foo(int name) { while (true) { if (ticket == name) { // 执行任务 System.out.println(name); ticket = name % 3 + 1; // 更新信号量 break; } } } ``` ### 3. 使用 `CompletableFuture` 实现顺序执行 `CompletableFuture` 提供了链式调用的特性,可以方便地实现多个线程顺序执行。 ```java CompletableFuture.runAsync(() -> { // 线程1的任务 }).thenRun(() -> { // 线程2的任务 }).thenRun(() -> { // 线程3的任务 }); ``` ### 4. 使用 `CountDownLatch` `CountDownLatch` 是一个同步工具类,它允许一个或多个线程等待其他线程完成操作。通过设置多个 `CountDownLatch`,可以控制线程执行顺序。 ```java CountDownLatch latch1 = new CountDownLatch(1); CountDownLatch latch2 = new CountDownLatch(1); new Thread(() -> { // 执行线程1的任务 latch1.countDown(); // 通知线程2可以开始 }).start(); new Thread(() -> { try { latch1.await(); // 等待线程1完成 // 执行线程2的任务 latch2.countDown(); // 通知线程3可以开始 } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { latch2.await(); // 等待线程2完成 // 执行线程3的任务 } catch (InterruptedException e) { e.printStackTrace(); } }).start(); ``` ### 5. 使用 `CyclicBarrier` `CyclicBarrier` 是一个同步辅助类,允许多个线程互相等待,直到所有线程都到达某个公共屏障点。通过设置屏障点,可以控制线程执行顺序。 ```java CyclicBarrier barrier = new CyclicBarrier(3); new Thread(() -> { // 执行线程1的任务 try { barrier.await(); // 等待其他线程 } catch (Exception e) { e.printStackTrace(); } }).start(); new Thread(() -> { // 执行线程2的任务 try { barrier.await(); // 等待其他线程 } catch (Exception e) { e.printStackTrace(); } }).start(); new Thread(() -> { // 执行线程3的任务 try { barrier.await(); // 等待其他线程 } catch (Exception e) { e.printStackTrace(); } }).start(); ``` ### 6. 使用 `Exchanger` `Exchanger` 是一个用于线程间协作的工具类,允许两个线程在某个点交换数据。通过设计交换逻辑,可以控制线程执行顺序。 ```java Exchanger<String> exchanger = new Exchanger<>(); new Thread(() -> { // 执行线程1的任务 try { exchanger.exchange("线程1完成"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); new Thread(() -> { try { String result = exchanger.exchange("线程2开始"); // 执行线程2的任务 } catch (InterruptedException e) { e.printStackTrace(); } }).start(); ``` ### 7. 使用 `Phaser` `Phaser` 是一种更灵活的同步工具,支持动态注册任务,并且可以分阶段同步多个线程。通过分阶段控制,可以实现线程顺序执行。 ```java Phaser phaser = new Phaser(); phaser.register(); // 注册当前线程 new Thread(() -> { // 执行线程1的任务 phaser.arriveAndAwaitAdvance(); // 等待其他线程 }).start(); new Thread(() -> { // 执行线程2的任务 phaser.arriveAndAwaitAdvance(); // 等待其他线程 }).start(); phaser.arriveAndDeregister(); // 注销当前线程 ``` ### 8. 使用 `ReentrantLock` 和条件变量 通过 `ReentrantLock` 和条件变量,可以实现更细粒度的线程控制,确保线程顺序执行。 ```java ReentrantLock lock = new ReentrantLock(); Condition condition1 = lock.newCondition(); Condition condition2 = lock.newCondition(); new Thread(() -> { lock.lock(); try { // 执行线程1的任务 condition1.signal(); // 通知线程2 } finally { lock.unlock(); } }).start(); new Thread(() -> { lock.lock(); try { condition1.await(); // 等待线程1完成 // 执行线程2的任务 condition2.signal(); // 通知线程3 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }).start(); new Thread(() -> { lock.lock(); try { condition2.await(); // 等待线程2完成 // 执行线程3的任务 } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } }).start(); ``` 这些方法各有优劣,选择合适的方法取决于具体的业务需求和场景。在实际应用中,可以根据任务的复杂性和依赖关系选择最合适的方式[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值