【问题标题】:Java library to maintain a process pool用于维护进程池的 Java 库
【发布时间】:2012-05-05 11:18:51
【问题描述】:

我正在开发一个需要并发的 Java 守护程序:一个无限循环,它侦听作业队列 (redis) 并将每个作业分配给工作人员。 worker 不一定要返回值。

我发现 Executors 非常有用,我正在使用 ThreadPoolExecutor 来维护多个工作线程。

不过,这些工作人员运行需要尽可能隔离运行的第 3 方代码,避免共享静态属性。

我的问题:是否有任何 Java 库/框架提供类似于 Executors 的功能,例如:

  • 工作人员池
  • 自动调整池大小

..但是产生进程而不是线程?

【问题讨论】:

    标签: java multithreading concurrency threadpool executorservice


    【解决方案1】:

    我了解您有想以某种方式隔离运行的第 3 方库 - 例如,它们无权访问静态变量。

    我会run your tasks in another ClassLoader。有一些 Web 框架使用这种机制来隔离 Web 请求。在类加载器之间传递数据有点棘手。我不确定 Jetty 是如何做到的。也许使用某种套接字?这是interesting article about using System.out to share objects。当然是黑客攻击。


    我的问题是:是否有任何 Java 库/框架提供类似于 Executors 的功能...但生成进程而不是线程?

    现代操作系统将利用现代多处理器架构来充分利用 Java 线程。如果可用,在当前进程中生成另一个线程将在另一个处理器上运行,并且将比在一个完全独立的进程中运行该任务更有效率,尤其是像另一个 JVM 进程一样繁重的进程。

    【讨论】:

    • 感谢您的回答@Gray,我明白您的意思。不过,在这种情况下,我需要让这些工作人员保持隔离(例如,防止共享静态变量等),并且可能在具有不同系统属性的 JVM 中运行它们。所以我的问题仍然存在,如果我需要运行多个进程(而不是线程),是否有可以提供帮助的框架?另外,请再次查看此 Q 的标题,因为我真正要问的是这样的框架是否存在,而不是使用它是否明智。
    • 你可以在另一个类加载器中运行它们。这就是 Web 服务器用来隔离类的方法。我不确定您将如何在两个类加载器之间传递数据。也许使用某种套接字:devx.com/java/Article/31614/1954
    • 谢谢@Gray;看来我必须做一些功课,看看这是否有帮助,然后回复你。
    • 恕我直言,避免使用静态变量比尝试让进程间通信在任何类型的高性能下正常工作更容易。
    • 在我看来@Martin 他正在使用 3rd 方代码或其他东西。
    【解决方案2】:

    您是否考虑过使用 ProcessBuilder 来管理您的隔离进程?

    String myJar = MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
    ProcessBuilder pb = new ProcessBuilder("java", "-classpath", myJar, "package.MainClass");
    Process p = pb.start();
    

    我不知道将管理子流程的 Runnable 任务提交给 Executor 是否是个好主意,但它可能是隔离工作人员的解决方案。

    【讨论】:

    • 嗯..刚看到这个..有趣的想法。正如您所指出的,我需要检查它是否有效,以及对 Executor 的任何影响。谢谢!
    【解决方案3】:

    github中有创建进程池的项目。看一看。 https://github.com/shri30/ProcessPool

    这是一个例子:

    示例代码:

    public class UsageExample implements JTask{
    
    
        public static void main(String args[]) throws Exception{
            //Create a pool with name : UsageExample-Process and number of processes : 3
            ExecutorService pool = ProcessPool.createProcessPool("UsageExample-Process", 3);
            ProcessFuture<TaskStatus> pf1 = pool.submit(Task.class, args);
            ProcessFuture<TaskStatus> pf2 =pool.submit(Task.class, args);
            ProcessFuture<TaskStatus> pf3 =pool.submit(Task.class, args);
            ProcessFuture<TaskStatus> pf4 =pool.submit(Task.class, args);
            ProcessFuture<TaskStatus> pf5 =pool.submit(Task.class, args);
            //the get method blocks the call to get the result
            TaskStatus ts= pf1.get();
            Status status = ts.getStatus();
            if(status == Status.SUCESS){
            //code goes here
            }
    
            TaskStatus ts2= pf2.get();
            Status status2 = ts.getStatus();
            if(status == Status.SUCESS){
            //code goes here
            }
    
    
            TaskStatus ts3= pf3.get();
            Status status3 = ts.getStatus();
            if(status == Status.SUCESS){
            //code goes here
            }
    
    
            TaskStatus ts4= pf4.get();
            Status status4 = ts.getStatus();
            if(status == Status.SUCESS){
            //code goes here
            }
            //terminate the pool - pass true for graceful termination, the second parameter is minutes
            //wait for task completion
            pool.terminate(true, 3000);
        }
    
    
    }
    
    class Task implements JTask{
    
        public static void main(String[] args) {
            System.out.println("Executing the sample task");
        }
    
    }
    

    【讨论】:

    • 请详细说明实际答案,不要只发布外部链接
    • 我继续为你详细说明
    猜你喜欢
    • 2015-05-11
    • 1970-01-01
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    相关资源
    最近更新 更多