当前位置: 首页 > 面试题库 >

在ThreadPoolExecutor中测试PriorityBlockingQueue

郎恺
2023-03-14
问题内容

我在这个示例中实现了具有PriorityBlockingQueue的ThreadPoolExecutor:http://codingdict.com/questions/131378

并写了一个测试:

PriorityExecutor executorService = (PriorityExecutor)  PriorityExecutor.newFixedThreadPool(16);
    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Thread.sleep(1000);
                System.out.println("1");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 1);

    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Thread.sleep(1000);
                System.out.println("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 3);

    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Thread.sleep(1000);
                System.out.println("2");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 2);

    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Thread.sleep(1000);
                System.out.println("5");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 5);

    executorService.submit(new Runnable() {
        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                Thread.sleep(1000);
                System.out.println("4");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }, 4);

    executorService.shutdown();
    try {
        executorService.awaitTermination(30, TimeUnit.MINUTES);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

但是最后,我没有得到1 2 3 4 5,我得到了这些数字的随机顺序。测试是否有问题,还是其他?如果首先,如何正确测试?


问题答案:

仅当池完全繁忙并且您提交了几个新任务时才考虑优先级。如果仅用一个线程定义池,则应获得预期的输出。在您的示例中,所有任务同时执行,并且首先完成的任务有些随机。

顺便说一下,如果您的队列已满并且您提交了新任务,则链接的实现会出现问题并引发异常。

请参见下面的工作示例,以了解要实现的目标(newTaskFor为了使之正常工作,我已经以一种简单化的方式进行了覆盖-您可能需要改进该部分)。

打印:1 2 3 4 5

public class Test {

    public static void main(String[] args) {
        PriorityExecutor executorService = (PriorityExecutor) PriorityExecutor.newFixedThreadPool(1);
        executorService.submit(getRunnable("1"), 1);
        executorService.submit(getRunnable("3"), 3);
        executorService.submit(getRunnable("2"), 2);
        executorService.submit(getRunnable("5"), 5);
        executorService.submit(getRunnable("4"), 4);

        executorService.shutdown();
        try {
            executorService.awaitTermination(30, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static Runnable getRunnable(final String id) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                    System.out.println(id);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
    }

    static class PriorityExecutor extends ThreadPoolExecutor {

        public PriorityExecutor(int corePoolSize, int maximumPoolSize,
                                long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {
            super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        }
        //Utitlity method to create thread pool easily

        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new PriorityExecutor(nThreads, nThreads, 0L,
                                        TimeUnit.MILLISECONDS, new PriorityBlockingQueue<Runnable>());
        }
        //Submit with New comparable task

        public Future<?> submit(Runnable task, int priority) {
            return super.submit(new ComparableFutureTask(task, null, priority));
        }
        //execute with New comparable task

        public void execute(Runnable command, int priority) {
            super.execute(new ComparableFutureTask(command, null, priority));
        }

        @Override
        protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) {
            return (RunnableFuture<T>) callable;
        }

        @Override
        protected <T> RunnableFuture<T> newTaskFor(Runnable runnable, T value) {
            return (RunnableFuture<T>) runnable;
        }
    }

    static class ComparableFutureTask<T> extends FutureTask<T> implements Comparable<ComparableFutureTask<T>> {

        volatile int priority = 0;

        public ComparableFutureTask(Runnable runnable, T result, int priority) {
            super(runnable, result);
            this.priority = priority;
        }

        public ComparableFutureTask(Callable<T> callable, int priority) {
            super(callable);
            this.priority = priority;
        }

        @Override
        public int compareTo(ComparableFutureTask<T> o) {
            return Integer.valueOf(priority).compareTo(o.priority);
        }
    }
}


 类似资料:
  • java.util.concurrent.ThreadPoolExecutor是一个ExecutorService,它使用可能的几个池化线程之一执行每个提交的任务,通常使用Executors工厂方法配置。 它还提供各种实用程序方法来检查当前线程统计信息并控制它们。 ThreadPoolExecutor方法 Sr.No. 方法和描述 1 protected void afterExecute(Run

  • 我有一个示例代码。 当我设置queueSize 2时,我得到了异常,因为threadpool执行器不能插入一个任务到队列中,当我设置queueSize 3时是可以的。我不明白为什么当我设置maxSize=4时,测试是可以的。它来自留档。 如果线程数小于corePoolSize,请创建一个新线程以运行新任务 如果线程数等于(或大于)corePoolSize,则将任务放入队列 如果队列已满,且线程数小

  • 我试图用Jasmine为Angularjs编写单元测试。这是我的控制器: 和测试 测试失败,即使我试图测试期望(true). toBe(true); 茉莉花,因果报应,棱角分明的嘲弄都在我的索引里。jasmine调试页面中的html,还有测试脚本。 我发现如果删除beforeach()块,expect(true)。托比(真的)通过了。 下面是一个错误:

  • 在Android Espresso测试中有什么好的方法来测试结果代码和数据吗?我在用浓缩咖啡2.0。 定义一个新方法,如并使用该方法以便可以截获,等等。 编写一个只用于测试的TestActivity,它将调用上的,并在中检查结果 试着思考这两个坏处中什么是较小的,或者是否有任何其他关于如何测试这一点的建议。有什么建议吗?谢了!

  • 问题内容: 我是Maven的新手,甚至是Clojure的新手。作为一种学习语言的练习,我正在编写蜘蛛纸牌播放器程序。 我已经配置了一个Maven目录结构,其中包含通常的src / main / clojure和src / test / clojure目录。我的pom.xml文件包含clojure-maven-plugin。当我运行“ mvn test”时,尽管我在src / test / cloj

  • 我试图使用XML和TestNG运行一个测试套件,但是我总是同时使用Eclipse和命令行得到相同的消息: 该文件已正确读取,但测试似乎没有运行。 以下是我的testng.xml的内容: 这是我的目录结构在Eclipse中的样子: 此外,这也是我试图通过命令行运行测试套件的方式: 我尝试过通过eclipse清理项目,但似乎没有帮助。我也试过跑步: < code>mvn clean,但它也没有完成工作