我正在研究一个需要并发的Java守护进程:一个无限循环,它侦听作业队列(redis)并将每个作业分配给worker。辅助角色不一定必须返回值。
我发现Executors非常有用,我正在使用ThreadPoolExecutor来维护许多工作线程。
但是,这些工作线程运行需要尽可能隔离运行的第三方代码,避免共享静态属性。
我的问题是:是否有任何Java库/框架提供类似于执行器的功能,例如:
- 辅助角色池
- 自动调整池大小
..但是生成进程而不是线程?
我知道您有想要以某种方式隔离运行的第三方库 - 因此它们无法访问静态变量。
我会在另一个ClassLoader
运行您的任务. 有一些 Web 框架使用此机制来隔离 Web 请求。在类加载器之间传递数据有点棘手。 我不确定Jetty是怎么做到的。 也许使用某种插座? 这是一篇关于使用 System.out
共享对象的有趣文章。 当然是黑客。
现代我的问题是:是否有任何 Java 库/框架提供类似于执行器的功能......但是生成进程而不是线程?
操作系统将利用现代多处理器架构来充分利用Java线程。 在当前进程中生成另一个线程将在另一个处理器上运行(如果可用),并且比在完全独立的进程中运行该任务要高效得多,尤其是像另一个 JVM 进程一样重的进程。
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");
}
}
您是否考虑过使用 ProcessBuilder 来管理隔离流程之类的方法?
String myJar = MyClass.class.getProtectionDomain().getCodeSource().getLocation().getPath());
ProcessBuilder pb = new ProcessBuilder("java", "-classpath", myJar, "package.MainClass");
Process p = pb.start();
我不知道将管理子流程的可运行任务提交给执行器是否是一个好主意,但它可能是隔离您的工作人员的解决方案。