简体   繁体   English

CDI多线程

[英]CDI multithreading

We want to optimize our application. 我们要优化我们的应用程序。 There is some streight linear work going on, that can be executed in multiple threads with smaller working sets. 正在进行一些线性的工作,可以在具有较小工作集的多个线程中执行。

Our typical service is accessed using the @Inject annotation from within our CDI-managed beans. 我们的典型服务是通过CDI管理的bean中的@Inject批注来访问的。 Also such a service could have it's own dependencies injected, ie: 同样,这样的服务可以注入自己的依赖项,即:

public class MyService {

   @Inject
   private OtherService otherService;

   @Inject
   private DataService1 dataService1;

   ...

   public void doSomething() {
     ...
   }
}

Because I can not use @Inject inside the class implementing Runnable . 因为我不能在实现Runnable的类中使用@Inject (It's not container managed.) I tried to pass the required services to the class before starting the thread. (它不是容器管理的。)我试图在启动线程之前将所需的服务传递给类。 So, using something like this, makes the service instance ( myService ) available within the thread: 因此,使用类似这样的方法,可使服务实例( myService )在线程内可用:

Class Thread1 implements Runnable{
   private MyService myService

   public Thread1(MyService myService){
      this.myService = myService;
   }

   public void run(){
      myService.doSomething();
   } 
}

Following the call-hierarchy the call to doStometing() is fine, because a reference to myService has been passed. 在调用层次结构之后,可以调用doStometing() ,因为已经传递了对myService的引用。 As far as I understand CDI, the injection is done the moment the attribute is accessed for the first time, meaning, when the doStomething() method tries to access either otherService or dataService1 , the injection would be performed. 据我了解的CDI,注入是在第一次访问属性时完成的,也就是说,当doStomething()方法尝试访问otherServicedataService1 ,将执行注入。

At that point however I receive an exception, that there is no context available. 但是到那时我收到一个例外,那就是没有可用的上下文。

I also tried to use the JBossThreadExecuter class instead of Plain-Threads - it leads to the very same result. 我还尝试使用JBossThreadExecuter类而不是Plain- JBossThreadExecuter它导致了完全相同的结果。

So the question would be, if there is a nice way to associate a context (or request) with a created Thread ? 所以问题是,是否存在将上下文(或请求)与创建的Thread相关联的好方法?

For EJB-Beans, I read that marking a method with @Asynchronous will cause the method to be run in a managed thread which itself will be wired to the context. 对于EJB-Beans,我读到用@Asynchronous标记方法将导致该方法在托管线程中运行,该托管线程本身将连接到上下文。 That would basically be exactly what I'm searching for. 那基本上就是我要寻找的。

Is there a way to do this in CDI? 有没有办法在CDI中做到这一点?

Or is there any way to obtain a context from within a unmanaged thread? 还是有任何方法可以从非托管线程中获取context

Weld allows programmatic context management, (there's an example in the official docs). Weld允许程序化上下文管理(官方文档中有一个示例)。

But before you go this way give EJBs a chance ) 但是在您采用这种方式之前,请给EJB一个机会)
@Async invocation functionality is there exactly for your case. @Async调用功能完全适合您的情况。 And as a bonus you'll get timeout interception and transaction management. 作为奖励,您将获得超时拦截和事务管理。

When you kick off an async process, your @RequestScoped and @SessionScoped objects are no longer in scope. 当您启动异步过程时,您的@RequestScoped@SessionScoped对象不再在范围内。 That's why you get resolution errors for the injected @RequestScoped objects. 因此,对于插入的@RequestScoped对象,您会得到解析错误。 Using @Stateless without a CDI scope is essentially @Dependent . 在没有CDI范围的情况下使用@Stateless本质上是@Dependent You can use @ApplicationScoped objects or if you're on CDI 1.1 you can start up @TransactionScoped . 您可以使用@ApplicationScoped对象,或者如果您使用的是CDI 1.1,则可以启动@TransactionScoped

You have to use JavaEE 7 feature, the managed executor. 您必须使用JavaEE 7功能,即托管执行程序。 So it will provide a context for your runnable. 因此,它将为您的可运行环境提供上下文。 I'm not sure if your JBoss version is JavaEE 7 compatible. 我不确定您的JBoss版本是否与JavaEE 7兼容。 At least Glassfish 4 is, and that approach works. 至少Glassfish 4就是这种方法。 See details here 在这里查看详细信息

Easiest Solution one can think of is Ejb Async. 人们能想到的最简单的解决方案是Ejb Async。

They are powerful, does the job and most importantly the concurrency is handled by the container(which could be an issue at some point of time if its not properly managed). 它们功能强大,可以完成工作,最重要的是,并发由容器处理(如果管理不当,在某些时候可能会成为问题)。

Just a simple use case lets say if we have written a rest service and each request spawns 10 threads(ex using CompletableFuture or anything) to do some long processing tasks and for an instance if 500 requests are made then how will the threads be managed, how the app behaves, does it waits for a thread from the thread pool, what is the timeout period, etc etc and to add to our comfort what happens when the threads are Deamon Threads. 举一个简单的用例,如果我们编写了一个rest服务,并且每个请求都产生10个线程(例如,使用CompletableFuture或其他任何东西)来执行一些长时间的处理任务,那么例如,如果发出500个请求,那么如何管理这些线程,应用程序的行为方式,是否等待线程池中的线程,超时时间等,以及使我们感到舒适的是,这些线程是Deamon线程时会发生什么。 We can avoid these overheads to some extent using EJBs. 使用EJB,我们可以在某种程度上避免这些开销。

Its always a good thing to have a friend from the technical services team to help us with all these container specific implementations. 有一个技术服务团队的朋友来帮助我们完成所有这些特定于容器的事情,总是一件好事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM