当前位置:首页 > 科技  > 软件

小米面试:如何实现优先级线程池?

来源: 责编: 时间:2024-05-20 17:53:42 297观看
导读我们知道,线程池中的所有线程都是由统一的线程工厂来创建的,当我们指定线程工厂时,线程池中的所有线程会使用我们指定的线程工厂来创建线程;但如果没有指定线程工厂,则会使用默认的线程工厂 DefaultThreadFactory 来创建线

EAW28资讯网——每日最新资讯28at.com

我们知道,线程池中的所有线程都是由统一的线程工厂来创建的,当我们指定线程工厂时,线程池中的所有线程会使用我们指定的线程工厂来创建线程;但如果没有指定线程工厂,则会使用默认的线程工厂 DefaultThreadFactory 来创建线程,核心源码如下:EAW28资讯网——每日最新资讯28at.com

DefaultThreadFactory() {    @SuppressWarnings("removal")    SecurityManager s = System.getSecurityManager();    group = (s != null) ? s.getThreadGroup() :                          Thread.currentThread().getThreadGroup();    namePrefix = "pool-" +                  poolNumber.getAndIncrement() +                 "-thread-";}

那么问题来了,面试官问的是“如何实现优先级线程池?”,为什么我们一上来先讲了线程工厂呢?EAW28资讯网——每日最新资讯28at.com

这是因为,当我们讲到线程池优先级的时候,我们首先会想到线程的优先级,所以按照惯性思考,当面试官问到如何使用实现优先级线程池时,我们首先会考虑是不是在创建线程池的时候,可以通过某种方法来创建不同的线程优先级,从而实现优先级线程池?这就是开头我们一上来就讲线程工厂的原因。EAW28资讯网——每日最新资讯28at.com

那在线程工厂中如何设置线程的优先级呢?EAW28资讯网——每日最新资讯28at.com

它的设置也比较简单,如下代码所示:EAW28资讯网——每日最新资讯28at.com

import java.util.concurrent.ThreadFactory;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class CustomThreadPoolExecutorDemo {    public static void main(String[] args) {        // 自定义线程工厂        ThreadFactory threadFactory = new CustomThreadFactory();        // 创建线程池        ThreadPoolExecutor executor = new ThreadPoolExecutor(2, 2, 0,                                                              TimeUnit.MILLISECONDS,                                                              new LinkedBlockingQueue<>(),                                                              threadFactory);        // 提交任务        executor.execute(() -> System.out.println("Task 1"));        executor.execute(() -> System.out.println("Task 2"));        // 关闭线程池        executor.shutdown();    }    static class CustomThreadFactory implements ThreadFactory {        @Override        public Thread newThread(Runnable r) {            Thread thread = new Thread(r);            // 设置线程优先级为最低优先级            thread.setPriority(Thread.MIN_PRIORITY);             return thread;        }    }}

但是这种方式也有问题,那就是线程工厂是统一的,所以即使能在线程工厂中设置线程的优先级,那么也是将整个线程池中的所有线程都设置成统一的优先级了,而不能解决咱们本文提出的问题的,那如何才能实现优先级线程池呢?EAW28资讯网——每日最新资讯28at.com

1.优先级线程池实现思路

转念一想,既然不能在线程优先级上下功夫,但我们是否可以在线程池的任务队列上动点心思呢?EAW28资讯网——每日最新资讯28at.com

此时我们想到,可以使用 PriorityBlockingQueue 优先级队列来对任务进行排序啊(PriorityBlockingQueue 天生支持按照优先级自动排序任务的),这样不就能保证优先级高的任务会被线程池优先获取并执行了嘛!EAW28资讯网——每日最新资讯28at.com

所以,有时候一条路走不通的时候,我们可以尝试换一个思路再试试。EAW28资讯网——每日最新资讯28at.com

2.优先级队列使用

我们先来测试一下 PriorityBlockingQueue 的使用,以尝试其可行性,示例代码如下:EAW28资讯网——每日最新资讯28at.com

import java.util.concurrent.PriorityBlockingQueue;public class PriorityBlockingQueueExample {    public static void main(String[] args) {        PriorityBlockingQueue<Task> priorityQueue = new PriorityBlockingQueue<>();        // 添加任务到优先级队列        priorityQueue.add(new Task("Task 1", 1));        priorityQueue.add(new Task("Task 4", 4));        priorityQueue.add(new Task("Task 3", 3));        priorityQueue.add(new Task("Task 2", 2));        // 从优先级队列中取出任务并执行        while (!priorityQueue.isEmpty()) {            Task task = priorityQueue.poll();            if (task != null) {                task.execute();            }        }    }    static class Task implements Comparable<Task> {        private String name;        private int priority;        public Task(String name, int priority) {            this.name = name;            this.priority = priority;        }        public void execute() {            System.out.println("Executing task: " + name);        }        @Override        public int compareTo(Task o) {            return Integer.compare(this.priority, o.priority);        }    }}

以上程序的执行结果如下:EAW28资讯网——每日最新资讯28at.com

EAW28资讯网——每日最新资讯28at.com

从上述结果和代码可以看出,我们添加任务的顺序是:1、4、3、2,但最终会按照优先级排队执行的顺序是:1、2、3、4,执行结果符合我们的预期,优先级高的任务先被执行了(数字越小,优先级越高)。EAW28资讯网——每日最新资讯28at.com

3.优先级线程池

因此,我们实现的优先级线程池的最终代码如下:EAW28资讯网——每日最新资讯28at.com

import java.util.concurrent.BlockingQueue;import java.util.concurrent.PriorityBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class PriorityThreadPool {    public static void main(String[] args) {        BlockingQueue<Runnable> queue = new PriorityBlockingQueue<>(1000);        ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1,                0, TimeUnit.SECONDS, queue        );        for (int i = 0; i < 100; i++) {            int finalI = i;            executor.execute(new PriorityTask(i, () -> {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    throw new RuntimeException(e);                }                System.out.println("优先级:" + finalI);            }));        }    }    static class PriorityTask implements Runnable, Comparable<PriorityTask> {        private final int priority;        private final Runnable task;        public PriorityTask(int priority, Runnable task) {            this.priority = priority;            this.task = task;        }        @Override        public void run() {            task.run();        }        @Override        public int compareTo(PriorityTask other) {            // 优先级高的任务应该排在前面(数字越小优先级越大)            return Integer.compare(this.priority, other.priority);        }    }}

以上程序执行结果如下:EAW28资讯网——每日最新资讯28at.com

EAW28资讯网——每日最新资讯28at.com

从上述结果可以看出,线程池是完全按照优先级从高到低的顺序执行的(数字越小优先级越高),如果将 compareTo 中的排序方法倒置之后,那么线程池的执行顺序就完全相反了,可见使用 PriorityBlockingQueue 实现优先级线程池的效果非常显著。EAW28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-89400-0.html小米面试:如何实现优先级线程池?

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Rust Tokio取消任务的几种模式,你知道吗?

下一篇: Python 高效编程的 15 个优秀实践

标签:
  • 热门焦点
  • 对标苹果的灵动岛 华为带来实况窗功能

    继苹果的灵动岛之后,华为也在今天正式推出了“实况窗”功能。据今天鸿蒙OS 4.0的现场演示显示,华为的实况窗可以更高效的展现出实时通知,比如锁屏上就能看到外卖、打车、银行
  • 6月安卓手机性价比榜:Note 12 Turbo断层式碾压

    6月份有一个618,虽然这是京东周年庆的日子,但别的电商也都不约而同的跟进了,反正促销没坏处,厂商和用户都能满意。618期间一些产品也出现了历史低价,那么各个价位段的产品性价比
  • 消息称迪士尼要拍真人版《魔发奇缘》:女主可能也找黑人演员

    8月5日消息,迪士尼确实有点忙,忙着将不少动画改成真人版,继《美人鱼》后,真人版《白雪公主》、《魔发奇缘》也在路上了。据外媒消息称,迪士尼将打造真人版
  • 学习JavaScript的10个理由...

    作者 | Simplilearn编译 | 王瑞平当你决心学习一门语言的时候,很难选择到底应该学习哪一门,常用的语言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 共享单车的故事讲到哪了?

    来源丨海克财经与共享充电宝相差不多,共享单车已很久没有被国内热点新闻关照到了。除了一再涨价和用户直呼用不起了。近日多家媒体再发报道称,成都、天津、郑州等地多个共享单
  • 签约井川里予、何丹彤,单视频点赞近千万,MCN黑马永恒文希快速崛起!

    来源:视听观察永恒文希传媒作为一家MCN公司,说起它的名字来,可能大家会觉得有点儿陌生,但是说出来下面一串的名字之后,或许大家就会感到震惊,原来这么多网红,都签约这家公司了。根
  • 大厂卷向扁平化

    来源:新熵作者丨南枝 编辑丨月见大厂职级不香了。俗话说,兵无常势,水无常形,互联网企业调整职级体系并不稀奇。7月13日,淘宝天猫集团启动了近年来最大的人力制度改革,目前已形成一
  • 自研Exynos回归!三星Galaxy S24系列将提供Exynos和骁龙双版本

    年初,全新的三星Galaxy S23系列发布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三个版本,全系搭载超频版骁龙8 Gen 2,虽同样采用台积电4nm工艺制
  • 滴滴违法违规被罚80.26亿 共存在16项违法事实

    滴滴违法违规被罚80.26亿 存在16项违法事实开始于2121年7月,历经一年时间,网络安全审查办公室对“滴滴出行”网络安全审查终于有了一个暂时的结束。据“网信
Top