JAVA cdi中文_java - 如何处理CDI创建的Runnable - SO中文参考 - www.soinside.com

我有一个Java SE项目接受将采取一些命令行参数在一个单独的线程中执行处理指定的参数。我正在使用以下焊接微线程配置依赖项进行注入

org.jboss.weld.se

weld-se-core

3.1.0.Final

org.wildfly

wildfly-microprofile-config-implementation

1.2.1

这是我的beans.xml

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"

version="1.1" bean-discovery-mode="all">

org.jboss.weld.environment.se.threading.RunnableDecorator

我的项目从以下主要类开始

@ApplicationScoped

public class Main {

@Inject

private Scheduler scheduler;

public void process(List types) throws InterruptedException {

scheduler.schedule(types);

}

public static void main(String[] args) throws InterruptedException {

SeContainerInitializer initializer = SeContainerInitializer.newInstance();

try (SeContainer container = initializer.initialize()) {

Main main = container.select(Main.class).get();

List argsList = Arrays.asList(args);

final List types = parseArguments(argsList);

main.process(types);

}

}

}

这是我的Scheduler类的代码

@ApplicationScoped

public class Scheduler {

private static final Duration DEFAULT_WAIT_TIME = Duration.ofSeconds(30);

@Inject

@ConfigProperty(name = "POOL_SIZE", defaultValue = "10")

@Getter

private int poolSize = 5;

@Inject

@ConfigProperty(name = "WAIT_DURATION", defaultValue = "PT30S")

@Getter

private String durationStr;

@Getter

private Duration waitDuration;

private ThreadPoolExecutor executor;

@Inject

private Instance exports;

@PostConstruct

public void init() {

executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(poolSize);

try {

waitDuration = Duration.parse(durationStr);

} catch (DateTimeException | NullPointerException e) {

waitDuration = DEFAULT_WAIT_TIME;

}

}

public void schedule(Collection types) throws InterruptedException {

if (types != null && !types.isEmpty()) {

//Spawn a new thread for each type

for(String type : types) {

ExportRunner runner = exports.get();

runner.setType(type);

executor.submit(runner);

}

} else {

throw new IllegalArgumentException("No FileTypes provided. Not performing export");

}

//Wait until every thread has completed

while(getTotalThreads() > 0) {

Thread.sleep(waitDuration.toMillis());

}

//shutdown executor which effectively ends the program

executor.shutdownNow();

}

public int getTotalThreads() {

return getActiveCount() + getQueueSize();

}

public int getActiveCount() {

return executor.getActiveCount();

}

public int getQueueSize() {

return executor.getQueue().size();

}

}

这是Runnable的骨架

@Dependent

public class ExportRunner implements Runnable {

@Setter

private FileType type;

//Has a custom producer and disposer

@Inject

@SEDataSource

private EntityManager em;

//Has a custom producer and disposer

@Inject

@SEDataSource

AlertService alertService;

//Has a custom producer and disposer

@Inject

@SEDataSource

HistoryService historyService;

@PostConstruct

private void init() {

//Set to same entity manager so that

//everythings happen inside single transaction

alertService.setEm(em);

historyService.setEm(em);

}

@PreDestroy

public void cleanup() {

log.info("ExporterRunner @PreDestroy was called");

}

public void run() {

try {

//do processing

} finally {

log.info("Processing Complete");

}

}

}

我遇到的问题是注入的对象(Runnable和包含的服务和EntityManager)并且在所有线程都已完成并执行executor.shutdown()命令之前永远不会被释放。

我相信,由于Runner被标记为@Dependent,它正在使用注入它的Object的Scope;这将使它成为@ApplicationScoped。我尝试使用@ThreadScoped(org.jboss.weld.environment.se.contexts.ThreadScoped)标记该类,如下所示

@ThreadScoped

public class ExportRunner implements Runnable {

...

}

但这会导致以下异常

org.jboss.weld.contexts.ContextNotActiveException: WELD-001303: No active contexts for scope type org.jboss.weld.environment.se.contexts.ThreadScoped

我觉得我需要使用@ActivateThreadScope(org.jboss.weld.environment.se.contexts.activators.ActivateThreadScope)注释,但我还没有找到任何如何使用它的示例。有谁知道我如何使我的Runnable不是@ApplicationScoped?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值