Android 线程优先级的设计

940 阅读2分钟

在Android开发中为了复用线程以及节约线程开销,线程池是使用较多的一种方法,有时也会有这样的需求,不同的线程执行任务的紧急度是不一样的,后加入线程池队列的任务可能需要优先处理,在ThreadPoolExecutor的构造函数中需要传递一个继承BlockQueue的子类。在SDK中已经提供了一个PriorityBlockingQueue这样的优先级阻塞队列,我们要做的就是扩展Runnable,添加一个优先级的属性。

public abstract class RunWithPriority implements Runnable{

public int priority;

public RunWithPriority(int priority){
    this.priority = priority;
}

public int getPriority() {
    return priority;
}

}

然后就是为PriorityBlockingQueue构造函数的第二个参数,继承Comparator实现一个比较优先级的类:

public class ComparePriority implements Comparator {

@Override
public int compare(T lhs, T rhs) {
    return rhs.getPriority() - lhs.getPriority();
}

}

完成了这个类之后我们就能实际使用了,写一个test类 public class Test {

public static void main(String[] args){
    //在PriorityBlockingQueue传入比较优先级的规则
    PriorityBlockingQueue<Runnable> queue = new PriorityBlockingQueue<>(20,new ComparePriority());
    Executor exe = new ThreadPoolExecutor(2,6,10, TimeUnit.SECONDS,queue);
    //RunWithPriority的构造函数中的数字就是优先级大小
    exe.execute(new RunWithPriority(2) {
        @Override
        public void run() {
            System.out.println(this.getPriority() + " started");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {
            }
            System.out.println(this.getPriority() + " finished");
        }
    });
    exe.execute(new RunWithPriority(10) {
        @Override
        public void run() {
            System.out.println(this.getPriority() + " started");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {

            }
            System.out.println(this.getPriority() + " finished");
        }
    });
    exe.execute(new RunWithPriority(5) {
        @Override
        public void run() {
            System.out.println(this.getPriority() + " started");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {

            }
            System.out.println(this.getPriority() + " finished");
        }
    });
    exe.execute(new RunWithPriority(3) {
        @Override
        public void run() {
            System.out.println(this.getPriority() + " started");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {

            }
            System.out.println(this.getPriority() + " finished");
        }
    });
    exe.execute(new RunWithPriority(4) {
        @Override
        public void run() {
            System.out.println(this.getPriority() + " started");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException ex) {

            }
            System.out.println(this.getPriority() + " finished");
        }
    });
}

}

我们通过输出log来看 10 started 2 started 10 finished 5 started 2 finished 4 started 5 finished 3 started 4 finished 3 finished

可以看出核心线程是2个 也就是刚开始进入的10 和 2 , 后面的调用顺序是5、3、4,在队列中经过优先级排列变成了5、4、3 ,真正的按照优先级的大小进行排列调用顺序来的。仅供参考。