Java Concurrency of Executor (return result processing) run multiple tasks and process the first result run multiple tasks and process all results


  • Run multiple tasks and process the first result
  • Run multiple tasks and process all results

Run multiple tasks and process the first result

A common problem with concurrent programming is that when multiple concurrent tasks are used to solve a problem, we tend to be interested in only the first result returned. For example, there are multiple sorting algorithms for an array, and it is possible to start all of them concurrently, but for a given array, the first algorithm that gets the sorted result is the fastest sorting algorithm.

We go through an instance which initiates two verification tasks, and as soon as one of them passes, it passes.

The class that implements the validation process has a simple logic that randomly validates whatever the username is, returning a random boolean.

package CreateExcutorInvokeAny;

import java.util.Random;
import java.util.concurrent.TimeUnit;

public class UserValidator {
    private String name;
    
    public UserValidator (String name) {
        this.name = name;
    }
    
    public boolean validate(String name,String password) {
        Random random = new Random();
        
        Long duration = (long)Math.random()*10;
        System.out.printf("Validator %s : Validator a user during %d seconds
", 
                this.name, duration);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
            return false;
        }
        
        return random.nextBoolean();
    }
    
    public String getName() {
        return this.name;
    }
}

Callable object, whose logic is to return the result if the validation passes, and to throw an exception if the validation does not pass.

package CreateExcutorInvokeAny;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class TaskValidator implements Callable<String> {
    
    private UserValidator validator;
    
    private String user;
    private String password;
    
    

    public TaskValidator(UserValidator validator, String user, String password) {
        super();
        this.validator = validator;
        this.user = user;
        this.password = password;
    }



    @Override
    public String call() throws Exception {
        if(!validator.validate(user, password)) {
            System.out.println(validator.getName() + "the user has not been found");
            throw new Exception("Error validating user");
        }
        System.out.println(validator.getName() + "has found");
        return validator.getName();
    }
    
}

Main class

package CreateExcutorInvokeAny;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {

    public static void main(String[] args) {
        String username = "test";
        String password = "test";
        UserValidator oneValidator = new UserValidator("one");
        UserValidator twoValidator = new UserValidator("two");
        TaskValidator oneTask = new TaskValidator(oneValidator, username, password);
        TaskValidator twoTask = new TaskValidator(twoValidator, username, password);
        List<TaskValidator> taskList = new ArrayList<>();
        taskList.add(oneTask);
        taskList.add(twoTask);
        
        ExecutorService executor = Executors.newCachedThreadPool();
        String res;
        
        try {
            res = executor.invokeAny(taskList);
            System.out.println("Main : res : " + res);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        
        executor.shutdown();
        System.out.println("Main : end of the execution");
    }

}

The key step here is the method invokeAny, which returns the result of the first task that finished execution, that is, if the validation did not pass and the task could not be executed to completion, naturally it will not complete and will not return, if the validation passed, it will return the result.

Our analysis of the procedure leads to four possibilities.

  • If both tasks return true, i.e. both pass the verification, then invokeany will return the first result that passes
  • If the first task validation returns true and the second task throws an exception, then the result of the invokeAny method is the name of the first task
  • If the first task throws an exception and the second task returns true, then the result of the second task is the return result
  • The last thing is that both tasks throw exceptions, then the invokeAny method will also throw an exception

image.png

image.png

image.png

image.png

Run multiple tasks and process all results

Executor allows concurrent tasks to be executed without having to think about thread creation and execution If you want to wait for a thread to finish, there are two ways to do it.

  • The isDone method of the Future interface will return true if the task has finished executing
  • After the shutdown method is called, the awaitTermination method of the ThreadPoolExecutor class puts the thread to sleep until all tasks have finished executing

All tasks can be executed using the invokeall method, which will wait until all tasks have been executed and then return.

Let's look at an example.

package CreateExecutorInvokeAll;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class Task implements Callable<Result> {
    
    private String name;
    
    public Task(String name) {
        this.name = name;
    }
    
    @Override
    public Result call() throws Exception {
        System.out.println(this.name + " Starting
");
        
        Long duration = (long)Math.random()*10;
        System.out.printf("Validator %s : Validator a user during %d seconds
", 
                this.name, duration);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        int value = 0;
        for(int i=0;i<5;i++) {
            value += (int)Math.random()*100;
        }
        
        Result res = new Result();
        res.setName(this.name);
        res.setValue(value);
        
        System.out.println(this.name + " end");
        return res;
    }
    
}
package CreateExecutorInvokeAll;

public class Result {
    
    private String name;
    private int value;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getValue() {
        return value;
    }
    public void setValue(int value) {
        this.value = value;
    }
    
    
}
package CreateExecutorInvokeAll;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Main {

    public static void main(String[] args) {
        
        ExecutorService executor = Executors.newCachedThreadPool();
        
        List<Task> tasklist = new ArrayList<>();
        
        for(int i=0;i<3;i++) {
            Task task = new Task(String.valueOf(i));
            tasklist.add(task);
        }

        List<Future<Result>> reslist = new ArrayList<>();
        
        try {
            reslist = executor.invokeAll(tasklist);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        executor.shutdown();
        
        System.out.println("Main : res");
        
        for(int i=0;i<reslist.size();i++) {
            Future<Result> future = reslist.get(i);
            
            try {
                Result res = future.get();
                System.out.println("result : " + res.getName() + "||" + res.getValue());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

}

running result

image.png


Recommended>>
1、More than the X7 BMW wants to develop more luxury cars to please the landed gentry
2、Unlocking the value of data sharing and opening up
3、Digital First Smart Leading 2018 Smart Manufacturing Innovation Competition in North China is Popular
4、The three outside hang cheat auxiliary universal version of the three outside auxiliary open hang software download
5、Python Foundation 4 Dictionary

    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号