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!