zoukankan      html  css  js  c++  java
  • Java Concurrency

    One of the advantages of the Executor framework is that you can run concurrent tasks that return a result. The Java Concurrency API achieves this with the following two interfaces:

    • Callable: This interface is similar to the Runnable interface. It has the call() method which you have to implement the logic of a task. The Callable interface is a parameterized interface, meaning you have to indicate the type of data the call() method will return.
    • Future: This interface has some methods to obtain the result generated by a Callable object and to manage its state.
    /**
     * This class calculates if a number is a prime number. 
     * It can be executed in an executor because it implements the Callable interface.
     * The call() method will return a String
     */
    public class PrimesCalculator implements Callable<String> {
    
        private int num;
    
        public PrimesCalculator(int num) {
            this.num = num;
        }
    
        /**
         * Method called by the executor to execute this task 
         * and calculate if a number is a prime number
         */
        @Override
        public String call() throws Exception {
            String msg = Primes.isPrime(num) ? String.format("%d is a prime number.", num)
                    : String.format("%d is not a prime number.", num);
            TimeUnit.SECONDS.sleep(new Random().nextInt(3));
            return msg;
        }
    }
    
    
    public class Main {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            
            // Create a ThreadPoolExecutor with fixed size. It has a maximun of two threads
            ThreadPoolExecutor executor=(ThreadPoolExecutor)Executors.newFixedThreadPool(2);
            // List to store the Future objects that control the execution of  the task and
            // are used to obtain the results
            List<Future<Integer>> resultList=new ArrayList<>();
    
            // Create a random number generator
            Random random=new Random();
            // Create and send to the executor the ten tasks
            for (int i=0; i<10; i++){
                Integer number=new Integer(random.nextInt(10));
                FactorialCalculator calculator=new FactorialCalculator(number);
                Future<Integer> result=executor.submit(calculator);
                resultList.add(result);
            }
            
            // Wait for the finalization of the ten tasks
            do {
                System.out.printf("Main: Number of Completed Tasks: %d
    ",executor.getCompletedTaskCount());
                for (int i=0; i<resultList.size(); i++) {
                    Future<Integer> result=resultList.get(i);
                    System.out.printf("Main: Task %d: %s
    ",i,result.isDone());
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            } while (executor.getCompletedTaskCount()<resultList.size());
            
            // Write the results
            System.out.printf("Main: Results
    ");
            for (int i=0; i<resultList.size(); i++) {
                Future<Integer> result=resultList.get(i);
                Integer number=null;
                try {
                    number=result.get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                System.out.printf("Core: Task %d: %d
    ",i,number);
            }
            
            // Shutdown the executor
            executor.shutdown();
    
        }
    
    }

    In this case, you have learned how to use the Callable interface to launch concurrent tasks that return a result. You have implemented the PrimesCalculator class that implements the Callable interface with String as the type of the result. Hence, it returns before type of the call() method.

    The other critical point of this example is in the Main class. You send a Callable object to be executed in an executor using the submit() method. This method receives a Callable object as a parameter and returns a Future object that you can use with two main objectives:

    • You can control the status of the task: you can cancel the task and check if it has finished. For this purpose, you have used the isDone() method to check if the tasks had finished.
    • You can get the result returned by the call() method. For this purpose, you have used the get() method. This method waits until the Callable object has finished the execution of the call() method and has returned its result. If the thread is interrupted while the get() method is waiting for the result, it throws an InterruptedException exception. If the call() method throws an exception, this method throws an ExecutionException exception.

    When you call the get() method of a Future object and the task controlled by this object hasn't finished yet, the method blocks until the task finishes. The Future interface provides another version of the get() method.

    • get(long timeout, TimeUnit unit): This version of the get method, if the result of the task isn't available, waits for it for the specified time. If the specified period of time passes and the result isn't yet available, the method returns a null value. The TimeUnit class is an enumeration with the following constants: DAYS, HOURS, MICROSECONDS, MILLISECONDS, MINUTES, NANOSECONDS, and SECONDS.
  • 相关阅读:
    矩阵论基础 3.1初等变换
    最优化理论与方法 9 二次规划
    最优化理论与方法 10 罚函数法
    矩阵论基础 2.5 用Matlab实现矩阵的基本运算
    最优化理论与方法 目录
    UG OPEN API编程基础 12UIStyler对话框
    第十四章 达朗伯原理 1
    矩阵论基础 2.3 方阵的几种运算
    矩阵论基础 3.5 用Matlab求解线性方程组
    测试一下博客的html代码机制
  • 原文地址:https://www.cnblogs.com/huey/p/6032951.html
Copyright © 2011-2022 走看看