T1、T2、T3三个线程怎么串行执行?

 这里只是一些简单基础的使用,自己浅薄的见解

1、使用 join() 

可以在一个线程中调用另一个线程的join()方法,使得当前线程等待被调用线程执行完毕后再继续执行。
通过在 T1 中调用 T2 的 join() 方法,确保 T2 执行完毕后才继续执行 T1,然后在 T2 中调用 T3 的 join() 方法,确保 T3 执行完毕后才继续执行 T2。

Thread t1 = new Thread(() -> {
    // T1的任务逻辑
    System.out.println("Thread T1 execute ");
});
Thread t2 = new Thread(() -> {
    try {
        t1.join(); // T2等待T1执行完成
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    // T2的任务逻辑
    System.out.println("Thread T2 execute ");
});
Thread t3 = new Thread(() -> {
    try {
        t2.join(); // T3等待T2执行完成
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    // T3的任务逻辑
    System.out.println("Thread T3 execute ");
});
t1.start();
t2.start();
t3.start();

注意的是,使用join()方法会阻塞当前线程,直到被等待的线程执行完成。

2、使用 Lock 和 Condition

可以使用 Lock 和 Condition 来实现线程之间的顺序执行。
在 T1 中调用 condition1.await() 方法等待条件满足,然后在 T2 中调用 condition1.signal() 方法唤醒 T1 继续执行,再在 T2 中调用 condition2.await() 方法等待条件满足,最后在 T3 中调用 condition2.signal() 方法唤醒 T2 继续执行。

public static void main(String[] args) {
    ThreeThreadExecuteSequentially example = new ThreeThreadExecuteSequentially();
    new Thread(example::thread1, "A").start();
    new Thread(example::thread2, "B").start();
    new Thread(example::thread3, "C").start();
}
// 线程执行的条件 1:线程1执行 2:线程2执行 3:线程3执行
int number = 1;
// 锁
Lock lock = new ReentrantLock();
// 从锁中获得3个条件变量
Condition condition1 = lock.newCondition();
Condition condition2 = lock.newCondition();
Condition condition3 = lock.newCondition();

// 第一个线程run之后执行的方法
public void thread1() {
    lock.lock();
    try {
        // 如果条件值不为1 就挂起等待
        while (number != 1) {
            condition1.await();
        }
        System.out.println("------1------");
        // 线程1 执行完毕 把变量设置为2
        number = 2;
        // 唤醒第2个条件变量
        condition2.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 不管抛没抛出异常都要解锁,防止线程死锁
        lock.unlock();
    }
}
public void thread2() {
    lock.lock();
    try {
        while (number != 2) {
            condition2.await();
        }
        System.out.println("------2------");
        number = 3;
        condition3.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}
public void thread3() {
    lock.lock();
    try {
        while (number != 3) {
            condition3.await();
        }
        System.out.println("------3------");
        number = 1;
        condition1.signal();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        lock.unlock();
    }
}

3、使用 CountDownLatch

可以使用 CountDownLatch 来实现线程之间的顺序执行。
在 T1 中调用 countDownLatch1.await() 方法等待计数器减到 0,然后在 T2 中调用 countDownLatch1.countDown() 方法减少计数器,再在 T2 中调用 countDownLatch2.await() 方法等待计数器减到 0,最后在 T3 中调用 countDownLatch2.countDown() 方法减少计数器。

// 创建两个 CountDownLatch 实例
CountDownLatch countDownLatch1 = new CountDownLatch(1);
CountDownLatch countDownLatch2 = new CountDownLatch(1);
// 创建线程 T1
Thread t1 = new Thread(() -> {
    try {
        // T1 线程等待计数器减到 0
        countDownLatch1.await();
        System.out.println("T1 is running");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
// 创建线程 T2
Thread t2 = new Thread(() -> {
    try {
        // T2 线程减少计数器
        countDownLatch1.countDown();
        // T2 线程等待计数器减到 0
        countDownLatch2.await();
        System.out.println("T2 is running");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
// 创建线程 T3
Thread t3 = new Thread(() -> {
    try {
        // T3 线程减少计数器
        countDownLatch2.countDown();
        System.out.println("T3 is running");
    } catch (Exception e) {
        e.printStackTrace();
    }
});
// 启动线程
t1.start();
t2.start();
t3.start();

4、使用CompletableFuture

CompletableFuture是JDK8的新特性。
CompletableFuture实现了CompletionStage接口和Future接口,前者是对后者的一个扩展,增加了异步会点、流式处理、多个Future组合处理的能力,使Java在处理多任务的协同工作时更加顺畅便利。

这里只简单的使用串行执行

// 创建三个CompletableFuture对象
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
    // 执行T1任务
    System.out.println("T1: " + Thread.currentThread().getName());
}).thenRunAsync(() -> {
    // 执行T2任务
    System.out.println("T2: " + Thread.currentThread().getName());
}).thenRunAsync(() -> {
    // 执行T3任务
    System.out.println("T3: " + Thread.currentThread().getName());
});
// 等待所有任务完成,并获取结果
future.join();

5、使用AsyncTool

https://gitee.com/jd-platform-opensource/asyncTool

这个工具是京东零售开源项目,是基于CompletableFuture进行封装的框架,弥补了CompletableFuture的不足。

  • worker: 一个最小的任务执行单元。通常是一个网络调用,或一段耗时操作。
  • callBack:对每个worker的回调。worker执行完毕后,会回调该接口,带着执行成功、失败、原始入参、和详细的结果。
  • wrapper:组合了worker和callback,是一个 最小的调度单元 。通过编排wrapper之间的关系,达到组合各个worker顺序的目的。

先创建三个worker

class TaskWorkerA implements IWorker<String, String>, ICallback<String, String> {

    /**
     * 在这里做耗时操作,如rpc请求、IO等
     */
    @Override
    public String action(String s, Map<String, WorkerWrapper> map) {
        System.out.println("TaskWorker A run ....");
        return "TaskWorker A";
    }


    @Override
    public void result(boolean b, String s, WorkResult<String> workResult) {

    }
}
.
.
.
.

然后开始串行任务

TaskWorkerA taskWorkerA = new TaskWorkerA();
TaskWorkerB taskWorkerB = new TaskWorkerB();
TaskWorkerC taskWorkerC = new TaskWorkerC();

WorkerWrapper<String, String> workerWrapper3 = new WorkerWrapper.Builder<String, String>()
        .worker(taskWorkerC)
        .callback(taskWorkerC)
        .param("3")
        .build();

WorkerWrapper<String, String> workerWrapper2 = new WorkerWrapper.Builder<String, String>()
        .worker(taskWorkerB)
        .callback(taskWorkerB)
        .param("2")
        .next(workerWrapper3)
        .build();

WorkerWrapper<String, String> workerWrapper1 = new WorkerWrapper.Builder<String, String>()
        .worker(taskWorkerA)
        .callback(taskWorkerA)
        .param("1")
        .next(workerWrapper2)
        .build();

try {
    Async.beginWork(1500, workerWrapper1);
} catch (Exception e) {
   e.printStackTrace();
}
Async.shutDown();

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值