将Context(CDI/servlet)注入新的FutureTask Thread

ian*_*its 2 java multithreading servlets futuretask cdi

我发现在servlet donot中创建的新线程包含servlet/CDI上下文.我创建了一个HelloWorld servlet(如下所示)来试验这个问题.在下面的示例中,您将看到我在新的Thread(FutureTask)中运行'doIt()'函数.但是它返回NULL但是当我直接调用'doIt()'方法时,BeanManager不是NULL.

/**
 * Servlet implementation class HelloWorld
 */
@WebServlet("/HelloWorld")
public class HelloWorld extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static Logger logger = Logger.getLogger(HelloWorld.class
            .getName());

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter writer = response.getWriter();

        writer.println("<html>");
        writer.println("<head><title>Hello World Servlet</title></head>");
        writer.println("<body>");
        writer.println("<h1>Context injection into Thread Experiment</h1>");
        try {
            // 1. This is NOT working
            new Thread(testTask).start();
            testTask.get(5000, TimeUnit.SECONDS);

            // 2. This is working
                //doIt();

        } catch (Exception e) {
            e.printStackTrace();
        }

        writer.println("<body>");
        writer.println("</html>");
        writer.close();         
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                doIt();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };

    FutureTask<Object> testTask = new FutureTask<Object>(runnable, null);

    protected void doIt() throws Exception {
        if(getBeanManager() == null) { 
            throw new Exception( "BEAN MANAGER IS NULL"); 
        }
    }

    public static BeanManager getBeanManager() {
        try {
            InitialContext initialContext = new InitialContext();
            return (BeanManager) initialContext.lookup("java:comp/BeanManager");
        } catch (NamingException e) {
            logger.info("Couldn't get BeanManager through JNDI");
            return null;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在网上搜索但找不到一个好的参考,而不是说它是可能的.如果有人可以帮助我或者为我提供一些注入/传递上下文到新线程的好指针,那将是很棒的.

Ken*_*Y-N 6

如果您使用的是EJB 3.1和Java EE 6或更高版本,则方法@Asynchronous上的符号使其在单独的线程中运行并负责管理资源等.

如果你需要更多的控制,正如Kalpesh Soni所指出的,如果你有Java EE 7或更高版本,这个答案将描述如何使用ManagedExecutorService.

另外,我不确定你是否真的需要那种getBeanManager()静态方法 - 不仅仅是@EJB BeanManager beanManager;(或@Inject)就足够了吗?