多线程按序打印如何实现?

1、题目

编写一个程序,开启 3 个线程,这 3 个线程的 ID 分别为 A、B、C,3 个线程交替打印 1-100 的整数,样例 Sample:

Thread1:1
Thread2:2
Thread3:3
Thread1:4
Thread2:5
Thread3:6
....
Thread3:99
Thread1:100

大家可以先思考一下,试试看看能否实现?

2、解题思路

题目中要求 3 个线程启动之后,需要按顺序一个接着一个来执行,重点是 3 个线程都处于运行状态,如何能让他们按顺序来打印?

大家可以把 3 个线程想象为 3 个人(ABC),ABC 3 个人手拉手组成一个环,然后 3 个人都坐那等通知,等谁的通知呢,等待上一个人的通知,B 等待 A 的通知,C 等待 B 的通知,A 等待 C 的通知。

刚开始:程序先唤起 A,A 打印之后,通知 B,然后 A 进入休眠等待唤醒通知,此时轮到 B 打印了,B 打印之后通知 C,B 进入休眠等待唤醒通知,此时轮到 C 打印了,C 打印之后通知 A,C 进入休眠等待唤醒通知,通过这种方式来实现,每个线程打印之后,负责唤醒下一个线程,然后自己进入休眠状态。

关键技术点有 2 个:

1、阻塞线程

2、唤起线程

java.util.concurrent.locks.LockSupport类刚好提供了 2 个静态方法支持这些操作

1、park():让当前线程阻塞

2、unpark(Thread thread):用来唤起阻塞中的线程

3、答案

代码相当简单。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.LockSupport;

public class ThreadTest {
    static List<Thread> threadList = new ArrayList<>();//存放线程的集合
    static int threadSize = 3;//总共多少个线程
    static int threadIndex = 0;//当前线程下标
    static int maxValue = 100;//需要输出的数的最大值
    static int curValue = 1;//数的当前值

    public static void main(String[] args) throws InterruptedException {
        //创建线程
        for (int i = 1; i <= threadSize; i++) {
            Thread thread = new Thread(() -> {
                while (true) {
                    //阻塞当前线程
                    LockSupport.park();
                    //当前的值需要小于最大值
                    if (curValue <= maxValue) {
                        System.out.println(Thread.currentThread().getName() + ":" + curValue++);
                    } else {
                        break;
                    }
                    //唤起下一个线程
                    LockSupport.unpark(threadList.get(++threadIndex % threadList.size()));
                }
                //唤起所有线程
                threadList.forEach(LockSupport::unpark);
            });
            thread.setName(String.format("Thread%d", i));
            threadList.add(thread);
        }

        //启动所有线程
        for (Thread thread : threadList) {
            thread.start();
        }

        //唤起第一个线程
        LockSupport.unpark(threadList.get(0));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值