【问题标题】:How can I avoid that each Thread creates a different pool?如何避免每个线程创建不同的池?
【发布时间】:2018-04-28 18:53:22
【问题描述】:

在我的程序中,我有一个名为“Vehicle”的类,它从 Thread 扩展而来,问题是在某个时候我需要这些 Threads 来创建一个任务(可运行),并且我希望所有这些任务都由同一个管理线程池,问题在于,如果我从包含此池的不同类调用方法,则每个其他线程都在创建不同的池。 我怎样才能避免这种情况? 提前致谢。

public class Station {
    Arrivals arrivals;
    Vehicle k;
    ListPumps lp;

    ExecutorService executor = Executors.newFixedThreadPool(3);
    public synchronized void startWork(Pump p) {

        Runnable w = new Work(p);
        executor.execute(w);

        executor.shutdown();
        while (!executor.isTerminated()) {
    }
        System.out.println("Finished all threads");
     }
}

【问题讨论】:

  • 如果我正确理解您的问题陈述,那么您可以将your different class 创建为单例。
  • 就是这样的方法,我试图写出声明方法,但我得到了相同的结果。
  • @J.FF 感谢您提供代码。我现在能够根据对下面代码的修改提供完整的答案。希望对您有所帮助。
  • 通过构造函数注入线程池实例呢?

标签: java multithreading concurrency threadpool


【解决方案1】:

您的代码已经使用了一个线程池。但是,如果您的类可能有多个实例,并且您希望它们都共享同一个线程池,则将其分配为静态变量。

虽然我现在也会将关闭代码提取到它自己的方法中。也不要轮询 isTerminated,使用 awaitTermination。

类似于以下内容:

public class Station {

    private Arrivals arrivals;
    private Vehicle k;
    private ListPumps lp;

    private static ExecutorService executor = Executors.newFixedThreadPool(3);

    public void startWork(Pump p) {
        Runnable w = new Work(p);
        executor.execute(w);
    }

    public static synchronized void shutdown() {
        executor.shutdown();
        if(executor.awaitTermination(60, TimeUnit.SECONDS))
            System.out.println("Finished all threads");
        else
            System.out.println("Executor shutdown timed out");
    }
}

【讨论】:

  • 这可以作为这个问题的评论的一部分。这没有回答问题。
  • 但是出于好奇,是否需要将startWork 设为同步?因为ExecutorService 将使用可用线程执行新任务,如果线程不空闲,那么任务将等待?
  • @Vishrant 我只是仔细检查了一下,你是正确的,执行方法实际上是线程安全的,但是似乎不是关闭(我可能在这里错了)。我将相应地修改我的示例。
  • 在我看来关机也是线程安全的。文档说Initiates an orderly shutdown in which previously submitted tasks are executed 但是This method does not wait for previously submitted tasks to complete execution
  • Vishrant 我不确定摘录是否真的说明它是线程安全的。如,从多个线程同时调用关闭是安全的。我强烈怀疑它是线程安全的,但在 javadocs 中没有明确提及。我根本找不到这方面的任何保证。
【解决方案2】:

两种选择:

  1. 您可以将ExecutorService 对象声明为静态,或者:
  2. 创建Station 类为singleton

我推荐阅读这篇文章: should ExecutorService be static and global

public class Station {

    private Arrivals arrivals;
    private Vehicle k;
    private ListPumps lp;

    // Bill Pugh Singleton Implementation
    private static class ExecutorServiceHelper {

        // volatile keyword to avoid CPU caching EXECUTOR object
        // famous volatile illutration http://tutorials.jenkov.com/images/java-concurrency/java-volatile-2.png
        private static volatile ExecutorService EXECUTOR = Executors
                .newFixedThreadPool(3);;

    }

    public ExecutorService getInstance() {
        return ExecutorServiceHelper.EXECUTOR;
    }

    // implementation of executor framework is threadsafe, so you don't need 
    // to use synchronized keyword on methods calling executors methods
    // here is the discussion https://stackoverflow.com/questions/1702386/is-threadpoolexecutor-thread-safe#answer-7596354
    public void submitWork(Pump p) {
        Runnable w = new Work(p);
        getInstance().execute(w);
    }

    public void shutdown() {
        getInstance().shutdown();
        if(getInstance().awaitTermination(60, TimeUnit.SECONDS))
            System.out.println("Finished all threads");
        else
            System.out.println("Executor shutdown timed out");
    }


}

【讨论】:

  • 您最近的编辑删除了我自己的编辑。您的代码原样不会编译。我修复了至少三个错误,您在编辑时删除了这些错误。
  • 哇!我没有意识到这一点。但是这三个错误是什么? @JeffreyPhillipsFreeman
  • 抱歉 5 个错误。我刚刚提交了一个修复了它们的编辑,你可以在他的差异中看到它们。
  • 感谢您的发现,我同意存在 1 个错误。在shutdown 方法中,我应该使用getInstance() 而不是executor,但其他方法是正确的,代码将编译。虽然我可以将 getInstance 方法设为静态,因为 J.FF 正在创建 Station 类的对象,但他将获得一个调用 getInstance 的实例,该实例将延迟加载 ExecutorServiceHelper 类。它只是另一种写法。 :) 我会接受你的一个编辑。 @JeffreyPhillipsFreeman
  • 您可以访问同一类中的私有变量。 imgur.com/HJ5AkMe 这是我刚刚在 Eclipse 中写的。这是我粘贴的图片的粘贴箱pastebin.com/ciR0Xae7@JeffreyPhillipsFreeman
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
  • 1970-01-01
  • 2023-04-04
  • 1970-01-01
  • 2021-12-18
相关资源
最近更新 更多