So far we have seen:
- In Part-1: Creating ManagedExecutorService to submit a single task or a list of tasks where each task would be an implementation of either Callable or Runnable interface.
- In Part-2: Creating ManagedScheduledExecutorService for scheduling tasks to run at a later time or to schedule repeating tasks.
In this post, which will be the final post showing the managed support for using Concurrency utilities in Java EE 7, I will show how to create a Thread using ManagedThreadFactory
. There is lot of difference between creating a Thread using ThreadFactory
or ManagedThreadFactory
and using ExecutorService
or ManagedExecutorService
to create a thread and submit it. In the latter there is a better way to manage the execution of the task by using the Future
class but in the former there is not much support. And the other difference being the ExecutorService
or ManagedExecutorService
leverages the ThreadFactory
or ManagedThreadFactory
underneath it.
As with all the other managed concurrency support, the Java EE 7 concurrency support provides ManagedThreadFactory API to create Thread managed by the application server. There is a default implementation which can be obtained by using JNDI lookup using the resource name: “java:comp/DefaultManagedThreadFactory”.
What is ManagedThreadFactory?
From the Javadocs:
A manageable version of a ThreadFactory.
A ManagedThreadFactory extends the Java™ SE ThreadFactory to provide a method for creating threads for execution in a Java™ EE environment. Implementations of the ManagedThreadFactory are provided by a Java™ EE Product Provider. Application Component Providers use the Java Naming and Directory Interface™ (JNDI) to look-up instances of one or more ManagedThreadFactory objects using resource environment references.
The only method present in the ManagedThreadFactory is: newThread() which it inherits from the ThreadFactory.
- newThread() Constructs a new Thread. Implementations may also initialize priority, name, daemon status, ThreadGroup, etc.
Using ManagedThreadFactory
In the below servlet- an instance of default ManagedThreadFactory is retrieved using JNDI lookup and then an new thread object is created using the factory.
import java.io.IOException; import java.io.PrintWriter; import java.util.logging.Level; import java.util.logging.Logger; import javax.enterprise.concurrent.ManagedThreadFactory; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(name = "ManagedThreadDemo", urlPatterns = {"/ManagedThreadDemo"}) public class ManagedThreadDemo extends HttpServlet { /** * Processes requests for both HTTP * <code>GET</code> * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException, NamingException { response.setContentType("text/html;charset=UTF-8"); final PrintWriter out = response.getWriter(); try { out.println("<!DOCTYPE html>"); out.println("<html>"); out.println("<head>"); out.println("<title>Servlet ManagedThreadDemo</title>"); out.println("</head>"); out.println("<body>"); out.println("<h1>Servlet ManagedThreadDemo at " + request.getContextPath() + "</h1>"); out.println("</body>"); out.println("</html>"); //Get the default ManagedThreadFactory implementation. InitialContext ctx = new InitialContext(); ManagedThreadFactory factory = (ManagedThreadFactory) ctx.lookup("java:comp/DefaultManagedThreadFactory"); //Create a new thread using the thread factory created above. Thread myThread = factory.newThread(new Runnable() { @Override public void run() { System.out.println("Running a task using Managed thread ..."); } }); //Start executing the thread. myThread.start(); } finally { out.close(); } } /** * Handles the HTTP * <code>GET</code> method. * * @param request servlet request * @param response servlet response * @throws ServletException if a servlet-specific error occurs * @throws IOException if an I/O error occurs */ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { processRequest(request, response); } catch (NamingException ex) { Logger.getLogger(ManagedThreadDemo.class.getName()). log(Level.SEVERE, null, ex); } } /** * Returns a short description of the servlet. * * @return a String containing servlet description */ @Override public String getServletInfo() { return "Short description"; } }