Планировщик JEE 7, как форк задачи без блокировки планировщика - PullRequest
0 голосов
/ 19 января 2020

В среде JEE 7 WildFly я хочу выполнить задачу (метод рабочего класса) без блокировки планировщика . Так что планировщик может запускать несколько «задач / потоков», которые выполняются независимо от планировщика (запускать и забывать).

В простом старом Java мне нужно только запустить новый поток, но в в управляемом контейнере это запрещено.

Как мне этого добиться?

Это короткий примитивный пример (который не работает ) для уточнить, что я хочу сделать:

@Startup
@Singleton
public class MyScheduler {

    public static final Logger LOGGER = LogManager.getLogger(MyScheduler.class);

    private int counter = 0;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    public void atSchedule() throws InterruptedException {

        LOGGER.info("{}. scheduler call - every five secs.", (++counter));

        final Worker worker = new Worker(counter);
        worker.doSomethingWithoutBlocking();

        LOGGER.info("Scheduler done.");

    }   

} // class MyScheduler 


@Stateless
@Asynchronous
public class Worker {

    public static final Logger LOGGER = LogManager.getLogger(Worker.class);

    private int nr; 

    public Worker() {}

    public Worker(final int nr) {
        this.nr = nr;
    }

    @Asynchronous
    public void doSomethingWithoutBlocking() {

        for(long i = 0; i < 10000000000L; i++) {

            if(i % 1000000000 == 0) {
                LOGGER.info("{}. Worker: i = {}", nr, i);
            } // if

        } // for

    }


} // class Worker

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Я бы посоветовал вам использовать ManagedExecutorService, который предоставляется сервером приложений. Учитывая, что вам не нужен класс Worker для EJB, приведенный ниже код должен справиться с задачей. Я не пытался запустить его на Wildfly, но подтвердил на сервере Payara.

@Singleton
public class Scheduler {
    private int counter = 0;
    private static final Logger LOGGER = Logger.getLogger(Scheduler.class.getName());

    @Resource
    ManagedExecutorService mes;

    @Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
    public void atSchedule() throws InterruptedException {
        LOGGER.info(String.format("%d. scheduler call - every five secs.", (++counter)));
        mes.submit(() -> {
            final Worker worker = new Worker(counter);
            worker.doSomething();
        });

        LOGGER.info("Scheduler done.");

    }   
}

public class Worker {
    private static final Logger LOGGER = Logger.getLogger(Worker.class.getName());
    private int nr; 

    public Worker() {}

    public Worker(final int nr) {
        this.nr = nr;
    }

    public void doSomething() {
        for(long i = 0; i < 10000000000L; i++) {
            if(i % 1000000000 == 0) {
                LOGGER.info(String.format("%d. Worker: i = %d", nr, i));
            } // if
        } // for
    }
}
0 голосов
/ 19 января 2020

Не думайте, что это лучшая идея, но:

@Startup
@Singleton
public class MyScheduler {

   public static final Logger LOGGER = LogManager.getLogger(MyScheduler.class);

private int counter = 0;


@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void atSchedule() throws InterruptedException {

    LOGGER.info("{}. scheduler call - every five secs.", (++counter));
    final Worker worker = new Worker(counter);
    runWithoutBlocking(worker);
    LOGGER.info("Scheduler done.");
}

@Async
void runWithoutBlocking(Worker worker) {
    worker.doSomethingWithoutBlocking();
}   

}

...