如何指定多个线程的执行顺序

一、问题定义
运行10个线程,按照顺序打印0123456789,Java代码实现!
二、具体实现

1、原始实现
设定一个orderNum,每个线程执行结束后,更新orderNum,指明下一个要执行的线程,并且唤醒所有的等待线程;在每一个线程的开始,要while判断orderNum是否等于自己的要求值,不是则wait,是则执行本线程。


public class OrderedThread extends Thread {

    private int id;
    private static int flag = 0;

    public OrderedThread(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        while (flag != id){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
        synchronized (OrderedThread.class){
            flag++;
        }
    }

    public static void main(String[] args) {
        OrderedThread[] orderedThreads = new OrderedThread[10];
        for (int i = 0; i < 10; i++) {
            orderedThreads[i] = new OrderedThread(i);
            orderedThreads[i].start();
        }
    }
}

2、使用join方法
使用join方法,让当前执行线程等待直到调用join()方法的线程结束运行,join()方法的主要作用是同步,使得线程之间的并行执行变为串行执行。

public class OrderedThreadUsingJoin extends Thread {
    private int id;

    public OrderedThreadUsingJoin(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
    }

    public static void main(String[] args) throws InterruptedException {
        OrderedThreadUsingJoin[] orderedThreadUsingJoins = new OrderedThreadUsingJoin[10];
        for (int i = 0; i < 10; i++) {
            orderedThreadUsingJoins[i] = new OrderedThreadUsingJoin(i);
            orderedThreadUsingJoins[i].start();
            /*
             程序在main线程中调用orderedThreadUsingJoins[i]线程的join方法,则main线程放弃cpu控制权,并返回
             orderedThreadUsingJoins[i]线程继续执行直到线程orderedThreadUsingJoins[i]执行完毕,然后到主线程执行,相当于
             在main线程中同步orderedThreadUsingJoins[i]线程,orderedThreadUsingJoins[i]执行完了,main线程才有执行的机会
             */
            orderedThreadUsingJoins[i].join();
        }
    }
}

注意:这里是main线程循环和orderedThreadUsingJoins[i]线程同步,因为所有子线程都是从main线程中启动的,这样就达到了顺序串行打印的目的!此外,join()的调用要在start()之后,不然无法起到同步的作用!

3、使用单线程池
使用单线程池,这样就能根据传入的顺序执行线程。


import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class OrderedThreadsUsingThreadPool extends Thread{
    private int id;

    public OrderedThreadsUsingThreadPool(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        System.out.printf("%s thread run, id is %s\n", Thread.currentThread().getName(), id);
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        OrderedThreadsUsingThreadPool[] orderedThreadsUsingThreadPools = new OrderedThreadsUsingThreadPool[10];
        for (int i = 0; i < 10; i++) {
            orderedThreadsUsingThreadPools[i] = new OrderedThreadsUsingThreadPool(i);
            executorService.execute(orderedThreadsUsingThreadPools[i]);
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值