[实践总结] 如何设置2个线程执行顺序

该文通过Java示例展示了如何控制线程的执行顺序。通过在TaskTwoJoinOne类中使用two.join(1000),确保线程two在1000毫秒内执行完毕后,线程one才会开始。如果线程two超过指定时间未完成,线程one将不再等待,两者将并发执行。这展示了Java中如何使用join()方法进行线程间的协调与同步。

正常情况下

public class TaskOne extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
        processCommand();
        System.out.println(Thread.currentThread().getName() + " → " + " End   Time = " + new Date());
    }

    private void processCommand() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class TaskTwo extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());
        processCommand();
        System.out.println(Thread.currentThread().getName() + " → " + " End   Time = " + new Date());
    }

    private void processCommand() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

TaskOne one = new TaskOne();
TaskTwo two = new TaskTwo();
one.start();
two.start();

执行结果

第1次执行第2次执行
Thread-0 → Start Time = Mon May 22 21:02:57 CST 2023Thread-1 → Start Time = Mon May 22 21:02:29 CST 2023
Thread-1 → Start Time = Mon May 22 21:02:57 CST 2023Thread-0 → Start Time = Mon May 22 21:02:29 CST 2023
Thread-0 → End Time = Mon May 22 21:03:01 CST 2023Thread-0 → End Time = Mon May 22 21:02:32 CST 2023
Thread-1 → End Time = Mon May 22 21:03:01 CST 2023Thread-1 → End Time = Mon May 22 21:02:32 CST 2023

总结

如果这样写的话线程one和线程two是交替执行的,但是不一定谁先启动。

如何让线程one在线程two前先执行呢?

线程two要在线程onerun里面创建,以此来保证两个线程的先后顺序

/**
 * 保证two在one后面执行
 */
public class TaskTwoInOne extends Thread {
    public void run() {
        System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());

        TaskTwo taskTwo = new TaskTwo();
        taskTwo.start();
        processCommand();

        System.out.println(Thread.currentThread().getName() + " → " + " End   Time = " + new Date());
    }

    private void processCommand() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

TaskTwoInOne one = new TaskTwoInOne();
one.start();

执行结果

第1次执行第2次执行
Thread-0 → Start Time = Mon May 22 21:11:56 CST 2023Thread-0 → Start Time = Mon May 22 21:13:17 CST 2023
Thread-1 → Start Time = Mon May 22 21:11:56 CST 2023Thread-1 → Start Time = Mon May 22 21:13:17 CST 2023
Thread-0 → End Time = Mon May 22 21:11:59 CST 2023Thread-1 → End Time = Mon May 22 21:13:20 CST 2023
Thread-1 → End Time = Mon May 22 21:11:59 CST 2023Thread-0 → End Time = Mon May 22 21:13:20 CST 2023

总结

以上只是保证,线程one比线程two先开始执行,但是后面就开始争抢资源不一定谁先结束。

如何让线程two执行完再执行线程one呢?

使用 join() 方法

public class TaskTwoJoinOne extends Thread {
    public void run() {
        System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());

        TaskTwo two = new TaskTwo();
        two.start();
        try {
            two.join(); // 线程two加入到线程one里,two执行完one才开始执行
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println(Thread.currentThread().getName() + " → " + " End   Time = " + new Date());
    }
}

执行结果

第1次执行结果分析
前置条件two.join();线程two加入到线程one里,two 执行完 one 才开始执行
Thread-0 → Start Time = Mon May 22 21:24:24 CST 2023线程one 开始
Thread-1 → Start Time = Mon May 22 21:24:24 CST 2023线程two join
Thread-1 → End Time = Mon May 22 21:24:27 CST 2023线程two 执行完毕
Thread-0 → End Time = Mon May 22 21:24:27 CST 2023线程one 执行完毕
前置条件two.join(2000);线程two加入到线程one里,线程one就等线程two 2000ms,超过2000ms后线程one就和线程two一起争抢资源了。如果线程two执行完不需要2000ms,则直接执行线程one内容,也不需要等够2000ms

总结

这样就太给线程two特权了,线程two不执行完,线程one就一直等着!!!

线程two执行完再执行线程one,如何给这个特权加个时效呢?

使用 join(1000) 方法

public class TaskTwoJoinOne extends Thread {
    public void run() {
        System.out.println(Thread.currentThread().getName() + " → " + " Start Time = " + new Date());

        TaskTwo two = new TaskTwo();
        two.start();
        try {
            two.join(1000);// 线程two加入到线程one里,就等线程two2000毫秒,超过就不等了

            // two.join(6000);// 最长需等6000ms,如果线程two执行完不需要6000ms,则可以继续执行线程one的内容
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        System.out.println(Thread.currentThread().getName() + " → " + " End   Time = " + new Date());
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值