Библиотека Java для поддержки пула процессов

Я работаю над демонами Java, для которых требуется concurrency: бесконечный цикл, который прослушивает очередь заданий (redis) и распределяет каждое задание рабочему. Работник не обязательно должен возвращать значение.

Я нашел Executors довольно полезным, и я использую ThreadPoolExecutor для поддержки ряда рабочих потоков.

Тем не менее, эти рабочие запускают сторонний код, который должен выполняться как изолированный, чтобы избежать использования статических свойств.

Мой вопрос: есть ли какая-либо библиотека Java/framework, которая предоставляет функции, похожие на Executors, например:

  • рабочие пулы
  • автоматически скорректированный размер пула

.. но нерест процессов вместо потоков?

Ответ 1

Я понимаю, что у вас есть сторонние библиотеки, которые вы хотите запускать изолированно, поэтому у них нет доступа, например, к статическим переменным.

Я бы запустил ваши задачи в другом ClassLoader. Существуют веб-фреймворки, которые используют этот механизм для изоляции веб-запросов. Передача данных между загрузчиками классов немного сложна. Я не уверен, как Jetty делает это. Может быть, используя какой-то сокет? Вот интересная статья об использовании System.out для обмена объектами. Конечно, взломать.


Мой вопрос: есть ли какая-нибудь библиотека/инфраструктура Java, которая предоставляет функции, аналогичные Executors... но порождает процессы вместо потоков?

Современные операционные системы будут использовать современные многопроцессорные архитектуры, чтобы максимально использовать потоки Java. Создание другого потока внутри вашего текущего процесса будет выполняться на другом процессоре, если он доступен, и будет гораздо более эффективным, чем запуск этой задачи в совершенно отдельном процессе, особенно в таком тяжелом, как другой процесс JVM.

Ответ 2

В 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");
    }

}

Ответ 3

Рассматривали ли вы что-то вроде использования ProcessBuilder для управления изолированным процессом?

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

Я не знаю, есть ли идея отправить Runnable задачи, которые управляют подпроцессами Исполнителю, но это может быть решение, чтобы изолировать ваших работников.