Callable + ThreadPoolExecutor multi-threaded and get the return value (turn)

Source: https://blog.csdn.net/kity9420/article/details/80740466

 

Foreword
  often encounter some performance issues, such as calling an interface, you may want to call the cycle 100 times, and the need to get every call to return results, we are usually placed for a time of serial loop calls this One can imagine how slow road ways, then how to solve this problem?

 

Multithreading
  To solve this problem, the way I am using multithreading. There are two conventional multi-threaded implementations that inherit Tread class that implements the Runnable interface, but the two implementations, there is a common problem, that is no return value, for us to get the return value of each thread, it is a very difficult problem, and therefore can not Tread class or Runnable interface, I use the Callable and ThreadPoolExecutor, Callable method allows the process to return to duty, ThreadPoolExecutor of invokeAll or submit method can get the results thread

 

Case
  is assumed to require user sends a message 100, and returns the result needs of each user, look at the code structure

               

  CallableTemplate.java 

Package com.gdut.thread.multiThread; 

Import java.util.concurrent.Callable; 

/ ** 
 * Template-based multithreaded 
 * @author yang.han 
 * 
 * @param <V>
  * / 
public  abstract  class CallableTemplate <V> the implements a Callable <V> { 
    
    / ** 
     * preprocessing, subclasses can Override this method 
     * / 
    public  void beforeProcess () { 
        System.out.println ( "before process" ); 
    } 
    
    / ** 
     * method for processing business logic requires subclasses to Override 
     * @param <V> 
     *@return
     */
    public abstract V process();
    
    /**
     * 后置处理,子类可以Override该方法
     */
    public void afterProcess() {
        System.out.println("after process");
    }

    @Override
    public V call() throws Exception {
        beforeProcess();
        V result = process();
        afterProcess();
        return result;
    }

}

  Callable CallableTemplate class implements the interface, and implement a process method, the class is an abstract class, receive any type of return value, beforeProcess pre-processing method, afterProcess post-processing, the specific process for the abstract service logic method, the A method implemented in a subclass

 

IConcurrentThreadPool.java

package com.gdut.thread.multiThread;

import java.util.List;
import java.util.concurrent.ExecutionException;

public interface IConcurrentThreadPool {

    /**
     * 初始化线程池
     */
    void initConcurrentThreadPool();
    
    /**
     * 提交单个任务
     * @param <V>
     * @param task
     * @return
     * @throws InterruptedException
     * @throws ExecutionException
     */
    <V> V submit(CallableTemplate<V> task) throws InterruptedException, ExecutionException;
    
    /**
     * 提交多个任务
     * @param <V>
     * @param tasks
     * @return
     * @throws InterruptedException 
     * @throws ExecutionException 
     */
    <V> List<V> invokeAll(List<? extends CallableTemplate<V>> tasks) throws InterruptedException, ExecutionException;
}

  IConcurrentThreadPool is multi-threaded interface class, three methods reputation, initConcurrentThreadPool: initialize the thread pool, submit: submit a single task thread, and the return value, invokeAll: submit multiple tasks of threads, and returns a value

 

ConcurrentThreadPool.java

package com.gdut.thread.multiThread;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ConcurrentThreadPool implements IConcurrentThreadPool{
    
    private ThreadPoolExecutor threadPoolExecutor;
    // 核心线程数
    private int corePoolSize = 10;
    // 最大线程数
    private int maximumPoolSize = 20;
    // 超时时间30秒
    private long keepAliveTime = 30;

    @Override
    public void initConcurrentThreadPool() {
        threadPoolExecutor = new ThreadPoolExecutor(corePoolSize,
                                                    maximumPoolSize, 
                                                    keepAliveTime, 
                                                    TimeUnit.SECONDS,
                                                    new LinkedBlockingDeque<Runnable>()
                                                    );
    }

    @Override
    public <V> V submit(CallableTemplate<V> task) throws InterruptedException, ExecutionException {
        Future<V> result = threadPoolExecutor.submit(task);
        return result.get();
    }

    @Override
    public <V> List<V> invokeAll(List<? extends CallableTemplate<V>> tasks) throws InterruptedException, ExecutionException {
        List<Future<V>> tasksResult = threadPoolExecutor.invokeAll(tasks);
        List<V> resultList = new ArrayList<V>();
        
        for(Future<V> future : tasksResult) {
            resultList.add(future.get());
        }
        return resultList;
    }

}

  ConcurrentThreadPool is to create a class that implements a thread pool, use the method and submit invokeAll ThreadPoolExecutor thread pool classes and methods of this class, the return value of these two methods, are available through the get method Future class

 

ICallableTaskFrameWork.java

package com.gdut.thread.multiThread;

import java.util.List;
import java.util.concurrent.ExecutionException;

public interface ICallableTaskFrameWork {
    <V> List<V> submitsAll(List<? extends CallableTemplate<V>> tasks)
            throws InterruptedException, ExecutionException;
}

  ICallableTaskFrameWork thread task framework interface is defined, all multi-threaded calls are initiated through this interface

 

CallableTaskFrameWork.java

package com.gdut.thread.multiThread;

import java.util.List;
import java.util.concurrent.ExecutionException;

public class CallableTaskFrameWork implements ICallableTaskFrameWork{

    private IConcurrentThreadPool concurrentThreadPool = new ConcurrentThreadPool();
    
    @Override
    public <V> List<V> submitsAll(List<? extends CallableTemplate<V>> tasks)
            throws InterruptedException, ExecutionException {
        concurrentThreadPool.initConcurrentThreadPool();
        return concurrentThreadPool.invokeAll(tasks);
    }

}

  CallableTaskFrameWork is ICallableTaskFrameWork implementation class, in submitsAll implement methods to initiate multi-threaded calls by invokeAll method calling thread pool object IConcurrentThreadPool interface, where attention one in submitAll implementation, I manually call the method to initialize the thread pool concurrentThreadPool.initConcurrentThreadPool (), on a real project, should the application starts to call this method to initialize the thread pool

Test class code 
SendMessageService.java , assume that this is a message to send e-mail service classes

package com.gdut.thread.multiThread;

public class SendMessageService {
    public void sendMessage(String email,String content){
        System.out.println("发送邮件。。。");
    }
}

 

SendMessageHander.java , multi-threaded sending mail processing class

package com.gdut.thread.multiThread;

import java.util.HashMap;
import java.util.Map;

public class SendMessageHander extends CallableTemplate<Map<String, String>>{
    
    private String email;
    private String content;
    public SendMessageHander(String email,String content) {
        this.email = email;
        this.content = content;
    }

    @Override
    public Map<String, String> process() {
        SendMessageService sendMessageService = new SendMessageService();
        sendMessageService.sendMessage(email, content);
        Map<String, String> map = new HashMap<String, String>();
        map.put(email, content);
        return map;
    }

}

  This class inherits the above CallableTemplate, we want the return value is a Map, and therefore generic type is Map, in the class also overrides the process approach, business logic interfaces SendMessageService.sendMessage calls to send mail in the process, and returns return result into an Map, where I a simple treatment, the e-mail address and the content in the Map return directly; Also note that this class has a constructor parameters have to be passed in the reception parameters required by the builder

 

SendMessageTest.java , test class

package com.gdut.thread.multiThread;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;

public class SendMessageTest {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ICallableTaskFrameWork callableTaskFrameWork = new CallableTaskFrameWork();
        
        List<CallableTemplate<Map<String, String>>> tasks = newThe ArrayList <CallableTemplate <the Map <String, String >>> (); 
        
        SendMessageHander sendMessageHander = null ; 
        
        // needs to be sent e-mail address and e-mail content is assembled, in a set 
        for ( int I = 0; I <1000; ++ I ) { 
            sendMessageHander = new new sendMessageHander ( "In email" + I, "Content" + I); 
            tasks.add (sendMessageHander); 
        } 
        
        // through multi-threaded disposable initiate message, and returns the result set to get 
        List <Map <String , String >> results = callableTaskFrameWork.submitsAll (Tasks); 
        
        // parse return a result set 
        for (the Map <String, String> Map:
            results) {
            for (Entry<String, String> entry : map.entrySet()) {
                System.out.println(entry.getKey() + "\t" + entry.getValue());
            }
        }
    }

}

operation result 

             

 

 

Appendix: You can also see the article here:  the Java programming concurrent asynchronous interface of the original ten live now only need one interface to get!

 

Guess you like

Origin www.cnblogs.com/myseries/p/11515370.html
Recommended