官术网_书友最值得收藏!

Concurrency Utilities for Java EE 1.0

Concurrency Utilities for Java EE 1.0 was developed under JSR 236. This section gives you only an overview of the API. The complete document specification (for more information) can be downloaded from http://jcp.org/aboutJava/communityprocess/final/jsr236/index.html.

Why concurrency?

In computer science, concurrency is the ability of an application or a system to execute many tasks in parallel. Before the advent of multitasking system, computers could only run one process at a time. At that time, the programs were not only difficult to design, but they were also executed sequentially from beginning to end and when the machine was running a program that had access to a peripheral device, the running program was first interrupted to allow the reading of the peripheral.

Benefits of concurrency

The development of multitasking operating systems enabled the simultaneous execution of many processes (instances of running programs) within a machine and many threads (also called lightweight processes; they are subsets of a process that can be run concurrently with each other) within a process. Due to this progress, it has become possible to run multiple applications at the same time, for example, listening to music and downloading a document while writing a text document.

In enterprise applications, concurrency can increase the interactivity of your program by running heavy processing asynchronously in a thread. It can also be used to improve the response time of an application by dividing a big task into smaller units that will be executed simultaneously by many threads.

Risks of concurrency

Although each thread has its proper stack of execution, it is very common to have multiple threads that share the same resources or depend on each other. In such cases, the absence of good synchronization makes threading behavior unpredictable and can degrade system performance. For example, the lack of coordination of interrelated threads can result in deadlocks and indefinitely interrupt processing.

Concurrency and Java EE

As we have seen previously, the misuse of threads can have catastrophic consequences on an application. In the case of a container, it could not only compromise its integrity, but also poorly exploit the resources provided to other components. This is one of the reasons why developers were not allowed to create threads in a container.

To enable implementation of concurrency within Java EE components, the Java EE 7 platform has integrated Concurrency Utilities. Using this API, a Java EE server can become aware of the resources that are used by threads and provide them with good execution context. Furthermore, it allows the server to manage the pool and lifecycle of threads.

Java EE Concurrency API

Concurrency Utilities for Java EE 1.0 was developed with the followings goals in mind:

  • To provide a simple and flexible concurrency API to the Java EE platform without compromising the container
  • To facilitate migration from Java SE to Java EE by providing consistency between the concurrency programming models
  • To allow the implementation of common and advanced concurrency patterns

Concurrency Utilities was built over the Concurrency Utilities API developed under JSR-166 for Java SE (which facilitates the migration from Java SE to Java EE). It offers four main programming interfaces whose instances must be made available to application components as container-managed objects. The offered interfaces are: ContextService, ManagedExecutorService, ManagedScheduledExecutorService, and ManagedThreadFactory. All these interfaces are contained in the javax.enterprise.concurrent package.

These four interfaces can be explained as follows:

  • Managed executor service: The ManagedExecutorService interface extends the java.util.concurrent.ExecutorService interface. It allows us to submit an asynchronous task that will be run on a separate thread created and managed by the container. By default, any Java EE 7-compliant server must provide a ManagedScheduledExecutorService that can be accessed by application components under the JNDI name java:comp/DefaultManagedScheduledExecutorService. But, if you want to create your own, you must first declare the ManagedExecutorService resource environment reference in the web.xml file for a web application or ejb-jar.xml for an EJB module. The specification recommends that all ManagedExecutorService resource environment references be organized in the java:comp/env/concurrent subcontext.
    • The following configuration is an example declaration of a ManagedExecutorService resource environment reference:
         <resource-env-ref>
                <resource-env-ref-name>
                  concurrent/ReportGenerator
                </resource-env-ref-name>
                <resource-env-ref-type>
                  javax.enterprise.concurrent.ManagedExecutorService
                </resource-env-ref-type>
              </resource-env-ref>
      Tip

      Downloading the example code

      You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

    • After declaring the JNDI reference, you can then inject it by using the @Resource annotation as shown in the following code:
       @Resource(name="concurrent/ReportGenerator")
              ManagedExecutorService reportGenerator;
    • The task to submit to the container must either implement the java.lang.Runnable or java.util.concurrent.Callable interface. The differences between these interfaces are presented in the following table:
    • The following code demonstrates how to define a task that will run reports asynchronously:
           public class ReportGeneratorTask implements Callable<String>{
              
                @Override
                public String call() throws Exception {
                  //generate report
                  return "The report was generated successfully";
                }   
              }
    • The following code shows us how to submit a task. We can see that the submit() method of the ManagedExecutorService instance returns an object of type Future that will get back the result of the running task when it becomes available:
       Future<String> monitor = reportGenerator
              .submit(new ReportGeneratorTask());
              String result = monitor.get();         
  • Managed scheduled executor service: The ManagedScheduledExecutorService interface extends the ManagedExecutorService and java.util.concurrent.ScheduledExecutorService interfaces in order to execute a task at a specific time.
    • Instances of this interface are defined in the same way as that of the ManagedExecutorService interface. The following code demonstrates how to execute a task ten seconds after its submission:
           Future<String> monitor = reportGenerator
                .schedule(new ReportGeneratorTask(), 10,TimeUnit.SECONDS);
  • Managed thread factory: The ManagedThreadFactory interface provides method to create managed thread instances in a container. The task must implement the java.lang.Runnable interface. The following code demonstrates how to create and run a container-managed thread.
    Thread myThread = threadFactory.newThread(new ReportManagedThread()); 
    myThread.start();
  • Context service: This interface allows the creation of contextual objects without using ManagedExecutorService or ManagedScheduledExecutorService interfaces, as we did in the previous cases, with the aim of allowing the extension of the capabilities of a Java EE platform for concurrency. Concretely, with this interface, you can create a workflow system or use customized Java SE platform ExecutorService implementations within a container. For example, if you desire to use the pool management mechanism provided by the class java.util.concurrent.ThreadPoolExecutor of Java SE to manage your threads in the context of a Java EE component, you will just need to combine ManagedThreadFactory, ExecutorService, and ContextService objects. The result is as shown in the following code:
    public class ReportCustomizedThread implements Runnable {
    
      public void run() {
        //Report processing ...
      }
    }
    
    @Resource(name=?concurrent/ReportManagedThreadGenerator?)
    ManagedThreadFactory threadFactory;
        
    @Resource(name=?concurrent/ReportContextServiceGenerator?)
    ContextService contextService; 
    
    ReportCustomizedThread reportThread = new ReportCustomizedThread();
    Runnable proxy =contextService.createContextualProxy(reportThread,Runnable.class);
    ExecutorService executorService =Executors.newFixedThreadPool(20, threadFactory);
    Future result = executorService.submit(proxy);
    //...

This is probably a simple example of the use you can make of this feature. For more advanced examples, please consult the specification document in the Context service section.

The following diagram provides an overview of relationships between Concurrency Utilities and other Java EE platform elements:

Besides, it is possible to refine the configurations of different resources for better performance (for details, see the specification document), and the Concurrency Utilities for Java EE 1.0 provide many other interfaces like ManagedTaskListener that can be used to monitor the state of a task's Future object.

主站蜘蛛池模板: 苏州市| 名山县| 九寨沟县| 夏邑县| 罗城| 邯郸县| 磴口县| 邵阳县| 柳河县| 陇西县| 长阳| 抚顺县| 卫辉市| 铜山县| 九江市| 邛崃市| 民乐县| 榆中县| 池州市| 商水县| 赞皇县| 洛扎县| 渝北区| 漾濞| 云林县| 广东省| 彩票| 霍林郭勒市| 吉安市| 库车县| 曲阳县| 建阳市| 大连市| 云南省| 芮城县| 西安市| 绍兴市| 汝城县| 涿鹿县| 温州市| 巴中市|