项目中数据库进行了水平切分,为了处理跨节点集合查询,采用了多线程并发操作的方式来处理,并且对各线程执行的结果进行操作,如果是返回结果集,则合并排序;如果是聚合操作,则求和。个人觉得该实现方式很有代表性,所以抽取了原型实现备忘。
集合处理:
import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; /** * 集合查询 * * 场景: 数据库水平切分后,集合查询要对所有数据源进行操作; * 例如: select count(*) from tablename,这个sql要广播到所有节点上执行; * 关键点: 对从各数据源查询得到的记录数进行求和. * * @author charles * */ public class Service { private static ExecutorService exec; private CompletionService<Object> completionService; public String invoke(String name){ //init fixedpool FixedConnectionPool fixedPool = new FixedConnectionPool(); exec = fixedPool.getExec(); completionService = fixedPool.getCompletionService(); for(int i = 0; i < 10; i++){ Task task = new Task(name); if (!exec.isShutdown()) { completionService.submit(task); } } return getResult(); } private String getResult(){ Object result = null; Object obj = null; for(int i = 0; i < 10; i++){ try { obj = completionService.take().get(); result = merge(obj,result); } catch (InterruptedException e) { System.out.println(">>>> Service InterruptedException : "+ e.getMessage()); e.printStackTrace(); obj = null; } catch (ExecutionException e) { System.out.println(">>>> Service ExecutionException : "+ e.getMessage()); e.printStackTrace(); obj = null; } catch(Exception e){ System.out.println(">>>> Service Exception : "+ e.getMessage()); e.printStackTrace(); obj = null; } } if(result != null) return (String)result; else return ""; } public String merge(Object obj, Object result) throws Exception { if(obj == null) obj = ""; if(result == null) result = ""; //System.out.println(">>>> merge : "+ obj +"\n"+ result); return obj +"\n"+ result; } public static void main(String[] args){ System.out.println(">>>> Interface : "+ new Service().invoke("冯天魁")); if (!exec.isShutdown()) exec.shutdown(); } }
任务:
/** * 任务 * @author charles * */ public class Task implements Callable<Object> { private String name; private static int i = 0; /** * i是多线程共享变量 */ public synchronized Object call() throws Exception { i++; return "Hello "+ name + i +", you are in a fixedpool!"; } public Task(String name){ this.name = name; } }
import java.util.concurrent.CompletionService; import java.util.concurrent.ExecutorCompletionService; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixedConnectionPool { private int cpuCoreNumber = 2; private ExecutorService exec; private CompletionService<Object> completionService; public FixedConnectionPool(){ this.cpuCoreNumber = Runtime.getRuntime().availableProcessors(); //this.exec = Executors.newCachedThreadPool(); this.exec = Executors.newFixedThreadPool(cpuCoreNumber); this.completionService = new ExecutorCompletionService<Object>(exec); } public int getCpuCoreNumber() { return cpuCoreNumber; } public void setCpuCoreNumber(int cpuCoreNumber) { this.cpuCoreNumber = cpuCoreNumber; } public ExecutorService getExec() { return exec; } public void setExec(ExecutorService exec) { this.exec = exec; } public CompletionService<Object> getCompletionService() { return completionService; } public void setCompletionService(CompletionService<Object> completionService) { this.completionService = completionService; } }