JEE 7 Scheduler 如何在不阻塞调度程序的情况下分叉任务
JEE 7 Scheduler how to fork a task without blocking the scheduler
在 JEE 7 WildFly 环境中,我想执行一个任务(worker 的一种方法class)而不阻塞调度程序。
这样调度程序就可以启动多个 "tasks/threads",它们 运行 独立于调度程序(即发即弃)。
在普通的旧 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
不要认为这是最好的主意,但是:
@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();
}
}
建议您使用应用服务器提供的ManagedExecutorService。鉴于您不需要 Worker class 成为 EJB,下面给出的代码应该可以解决问题。我还没有在 Wildfly 上尝试 运行,但在 Payara Server 上进行了验证。
@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
}
}
在 JEE 7 WildFly 环境中,我想执行一个任务(worker 的一种方法class)而不阻塞调度程序。 这样调度程序就可以启动多个 "tasks/threads",它们 运行 独立于调度程序(即发即弃)。
在普通的旧 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
不要认为这是最好的主意,但是:
@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();
}
}
建议您使用应用服务器提供的ManagedExecutorService。鉴于您不需要 Worker class 成为 EJB,下面给出的代码应该可以解决问题。我还没有在 Wildfly 上尝试 运行,但在 Payara Server 上进行了验证。
@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
}
}