1 import java.util.ArrayList; 2 import java.util.Collections; 3 import java.util.Date; 4 import java.util.HashMap; 5 import java.util.List; 6 import java.util.Map; 7 import java.util.UUID; 8 import java.util.concurrent.ConcurrentHashMap; 9 import java.util.concurrent.ExecutorService; 10 import java.util.concurrent.Executors; 11 import java.util.concurrent.TimeUnit; 12 import java.util.concurrent.atomic.AtomicInteger; 13 14 import org.apache.commons.lang.StringUtils; 15 /** 16 * 工作组 17 * @author Administrator 18 * 19 */ 20 final class WorkerGroup <T>{ 21 private ExecutorService executor=Executors.newScheduledThreadPool(10); 22 private List<T> workerGroupResult=Collections.synchronizedList(new ArrayList<T>());//任务结果集合 23 private AtomicInteger taskNum=new AtomicInteger(0);//任务完成个数统计 24 private List<WorkerGroupTask<T>> taskTable=Collections.synchronizedList(new ArrayList<WorkerGroupTask<T>>());//任务表 25 private Map<String,Long> taskRunTimeStatis=new ConcurrentHashMap<String, Long>();//任务完成时间统计 26 public boolean isFinishedTask=false;//工作组完成标志 27 private T workerResult=null;//任务结果 28 private Worker.FinshedCallable<T> finshedCallable=null;//工作组任务完成回调接口 29 private Map<Long,Thread> taskThreadTable=new ConcurrentHashMap<Long, Thread>(); 30 31 /** 32 * 返回工作组处理后的结果 33 * @return 34 */ 35 public T getWorkerResult(){ 36 return this.workerResult; 37 } 38 39 /** 40 * 添加工作组完成回调接口 41 * @param finshedCallable 42 */ 43 public void addFinshedCallable(Worker.FinshedCallable<T> finshedCallable){ 44 this.finshedCallable=finshedCallable; 45 } 46 //添加任务 47 public void addWorkerGroupTask(WorkerGroupTask<T> worker){ 48 taskTable.add(worker); 49 } 50 //工作组完成时间统计 51 public Long finishedTime(){ 52 Long l=0l; 53 for(Map.Entry<String, Long> map :taskRunTimeStatis.entrySet()){ 54 l+=map.getValue(); 55 } 56 return l; 57 } 58 /** 59 * 获取工作组中每个任务的执行时间 60 * @return 61 */ 62 public Map<String,Long> getTaskRunTimeMap(){ 63 return this.taskRunTimeStatis; 64 } 65 /** 66 * 启动工作组 67 */ 68 public void runWorkerGroupTask(){ 69 try { 70 for(WorkerGroupTask<T> task :taskTable){ 71 executor.execute(task); 72 } 73 } catch (Exception e) { 74 e.printStackTrace(); 75 isFinishedTask=true; 76 throw new RuntimeException(e); 77 } 78 } 79 80 /** 81 * 关闭工作组 82 */ 83 public void closeWorkGroup(){ 84 try { 85 boolean awaitTermination = executor.awaitTermination(1, TimeUnit.MILLISECONDS); 86 if(!awaitTermination){ 87 System.out.println("我关闭了"); 88 executor.shutdownNow(); 89 } 90 } catch (Exception e) { 91 throw new RuntimeException(e); 92 }finally{ 93 isFinishedTask=true; 94 for(Map.Entry<Long, Thread> thread:taskThreadTable.entrySet()){ 95 try { 96 thread.getValue().interrupt(); 97 } catch (Exception e2) { 98 e2.printStackTrace(); 99 } 100 101 } 102 } 103 } 104 /** 105 * 更新任务完成个数,并结束工作组 106 */ 107 public void isShutDownWorkerGroup(){ 108 try { 109 int finshTaskNumber=taskNum.incrementAndGet();//完成的任务数 110 if(taskTable.size() == finshTaskNumber){ 111 System.out.println("线程池关闭了..运行了:"+finishedTime()); 112 if(null != finshedCallable){ 113 workerResult=finshedCallable.workerGroupFinshedCallable(workerGroupResult); 114 } 115 isFinishedTask=true; 116 executor.shutdown(); 117 } 118 } catch (Exception e) { 119 isFinishedTask=true; 120 executor.shutdown(); 121 } 122 } 123 124 /** 125 * 工作组任务 126 * @author Administrator 127 * 128 */ 129 abstract class WorkerGroupTask<R extends T> implements WorkerGroupTaskCallBack<R>, Runnable{ 130 private String taskName=UUID.randomUUID().toString(); 131 private Long startTime=0l; 132 public WorkerGroupTask(String taskName){ 133 if(StringUtils.isNotBlank(taskName)){ 134 this.taskName=taskName; 135 } 136 } 137 138 @Override 139 public final void run() { 140 try { 141 before(); 142 R taskResult=task(); 143 after(taskResult); 144 } catch (Exception e) { 145 throw new RuntimeException(e); 146 } 147 148 } 149 @Override 150 public void after(R c) { 151 workerGroupResult.add(c); 152 taskThreadTable.remove(Thread.currentThread().getId()); 153 taskRunTimeStatis.put(taskName, new Date().getTime()-startTime); 154 isShutDownWorkerGroup(); 155 }; 156 @Override 157 public void before() { 158 startTime=new Date().getTime(); 159 taskThreadTable.put(Thread.currentThread().getId(), Thread.currentThread()); 160 } 161 public abstract R task(); 162 } 163 /** 164 * 工作组任务回调 165 * @author Administrator 166 * 167 * @param <C> 168 */ 169 private interface WorkerGroupTaskCallBack<C> { 170 /** 171 * 任务运行前通知 172 */ 173 void before(); 174 /** 175 * 任务运行后通知,返回任务结果 176 * @param c 177 */ 178 void after(C c); 179 } 180 } 181 ======================================================================================== 182 import java.util.ArrayList; 183 import java.util.List; 184 import java.util.Map; 185 import java.util.Timer; 186 import java.util.TimerTask; 187 import java.util.concurrent.BlockingDeque; 188 import java.util.concurrent.Callable; 189 import java.util.concurrent.ConcurrentHashMap; 190 import java.util.concurrent.ExecutorService; 191 import java.util.concurrent.Executors; 192 import java.util.concurrent.Future; 193 import java.util.concurrent.LinkedBlockingDeque; 194 195 import org.apache.commons.lang.StringUtils; 196 197 198 public final class Worker<W> { 199 private String workerName; 200 private InnerWorker innerWorker; 201 private Long timeout=10000l; 202 public Worker(String workerName,Long timeout){ 203 if(StringUtils.isBlank(workerName)){ 204 throw new RuntimeException("工作容器名字不能为空"); 205 } 206 this.workerName=workerName; 207 this.timeout=timeout; 208 this.innerWorker=newInstanceInnerWorker(); 209 210 if(null != innerWorker.workerGroupTable.get(this.workerName)){ 211 innerWorker.workerGroupTable.remove(this.workerName); 212 innerWorker.workerRunTimeLinster.remove(this.workerName); 213 this.innerWorker.blc.push(innerWorker.workerGroupTable.get(this.workerName)); 214 innerWorker.workerRunTimeLinster.put(this.workerName,0l); 215 }else{ 216 innerWorker.workerRunTimeLinster.put(this.workerName,0l); 217 innerWorker.workerGroupTable.put(this.workerName, new ArrayList<WorkerGroup>()); 218 } 219 } 220 221 public W forkResult(FinshedCallable<W> finshedCallable){ 222 if(StringUtils.isBlank(this.workerName)){ 223 throw new RuntimeException("工作容器名字不能为空"); 224 } 225 final List<WorkerGroup> workerGroupList=innerWorker.workerGroupTable.get(this.workerName); 226 for(WorkerGroup group:workerGroupList){ 227 group.runWorkerGroupTask(); 228 } 229 Callable<List<W>> result=new Callable<List<W>>() { 230 public List<W> call() throws Exception { 231 List<W> rs=new ArrayList<W>(); 232 int a=0; 233 while(a<workerGroupList.size()){ 234 for(WorkerGroup group:workerGroupList){ 235 if(group.isFinishedTask){ 236 rs.add((W)group.getWorkerResult()); 237 group.isFinishedTask=false; 238 a++; 239 } 240 } 241 ///如果超时就结束 242 if(innerWorker.workerRunTimeLinster.get(workerName) > timeout){ 243 System.out.println(innerWorker.workerRunTimeLinster.get(workerName) + "=="+timeout); 244 innerWorker.blc.push(innerWorker.workerGroupTable.get(workerName)); 245 innerWorker.workerGroupTable.remove(workerName); 246 innerWorker.workerRunTimeLinster.remove(workerName); 247 throw new RuntimeException("运行超时"); 248 }; 249 } 250 innerWorker.workerGroupTable.remove(workerName); 251 innerWorker.workerRunTimeLinster.remove(workerName); 252 return rs; 253 } 254 }; 255 Future<List<W>> submit = innerWorker.executor.submit(result); 256 W r=null; 257 try { 258 r= finshedCallable.workerFinshedCallable(submit.get()); 259 } catch (Exception e) { 260 e.printStackTrace(); 261 if(innerWorker.workerGroupTable.get(this.workerName)!=null){ 262 this.innerWorker.blc.push(innerWorker.workerGroupTable.get(this.workerName)); 263 innerWorker.workerGroupTable.remove(this.workerName); 264 } 265 } 266 return r; 267 } 268 public <W> void addWorkerGroup(WorkerGroup<W> workerGroup){ 269 if(StringUtils.isBlank(this.workerName)){ 270 throw new RuntimeException("工作容器名字不能为空"); 271 } 272 innerWorker.workerGroupTable.get(this.workerName).add(workerGroup); 273 } 274 275 276 private static class InnerWorker{ 277 public ExecutorService executor=Executors.newScheduledThreadPool(10); 278 public Map<String,List<WorkerGroup>> workerGroupTable=new ConcurrentHashMap<String,List<WorkerGroup>>();//worker表 279 public BlockingDeque<List<WorkerGroup>> blc = new LinkedBlockingDeque<List<WorkerGroup>>();//重复执行的Work需要移除 280 public boolean workerForkFinished=false;//如果设置true结束所有任务 281 public Map<String,Long> workerRunTimeLinster=new ConcurrentHashMap<String, Long>(); 282 public Timer timer=new Timer(); 283 public InnerWorker(){ 284 timer.schedule(new TimerTask() { 285 @Override 286 public void run() { 287 try { 288 for(Map.Entry<String, Long> entry:workerRunTimeLinster.entrySet()){ 289 workerRunTimeLinster.put(entry.getKey(), entry.getValue()+10l); 290 } 291 if(workerForkFinished){ 292 for(Map.Entry<String, List<WorkerGroup>> entry:workerGroupTable.entrySet()){ 293 for(WorkerGroup g : entry.getValue()){ 294 g.isShutDownWorkerGroup(); 295 } 296 workerGroupTable.remove(entry.getKey()); 297 workerRunTimeLinster.remove(entry.getKey()); 298 } 299 return ; 300 } 301 if(blc.size()>0){ 302 List<WorkerGroup> gl=blc.poll(); 303 for(WorkerGroup g : gl){ 304 g.closeWorkGroup(); 305 } 306 } 307 } catch (Exception e) { 308 e.printStackTrace(); 309 } 310 } 311 }, 0, 10); 312 } 313 } 314 315 316 private static InnerWorker newInstanceInnerWorker(){ 317 return InnerWorkerHandler.single; 318 } 319 private static class InnerWorkerHandler{ 320 private static final InnerWorker single = new InnerWorker(); 321 } 322 323 interface FinshedCallable<F>{ 324 public F workerFinshedCallable(List<F> workerSet); 325 public F workerGroupFinshedCallable(List<F> workerGroupSet); 326 327 } 328 } 329 ======================================================================================== 330 import java.math.BigDecimal; 331 import java.util.List; 332 333 public class TaskTest { 334 public static void main(String[] args) { 335 Worker<BigDecimal> worker=new Worker<BigDecimal>("1", 30000l); 336 Worker.FinshedCallable<BigDecimal> com=new Worker.FinshedCallable<BigDecimal>() { 337 @Override 338 public BigDecimal workerFinshedCallable( 339 List<BigDecimal> workerSet) { 340 BigDecimal total=new BigDecimal(0); 341 for(BigDecimal t:workerSet){ 342 total=total.add(t); 343 } 344 return total; 345 } 346 347 @Override 348 public BigDecimal workerGroupFinshedCallable( 349 List<BigDecimal> workerGroupSet) { 350 BigDecimal total=new BigDecimal(0); 351 for(BigDecimal t:workerGroupSet){ 352 total=total.add(t); 353 } 354 return total; 355 } 356 }; 357 358 WorkerGroup<BigDecimal> workerGroup = new WorkerGroup<BigDecimal>(); 359 360 workerGroup.addWorkerGroupTask(workerGroup.new WorkerGroupTask<BigDecimal>("我是工作组") { 361 @Override 362 public BigDecimal task() { 363 BigDecimal a=new BigDecimal(0); 364 for(int i=0;i<Integer.MAX_VALUE/2;i++){ 365 a=a.add(new BigDecimal(i)); 366 } 367 return a; 368 } 369 }); 370 workerGroup.addWorkerGroupTask(workerGroup.new WorkerGroupTask<BigDecimal>("我是工作组") { 371 @Override 372 public BigDecimal task() { 373 BigDecimal a=new BigDecimal(0); 374 for(int i=Integer.MAX_VALUE/2;i<Integer.MAX_VALUE;i++){ 375 a=a.add(new BigDecimal(i)); 376 } 377 return a; 378 } 379 }); 380 381 workerGroup.addFinshedCallable(com); 382 worker.addWorkerGroup(workerGroup); 383 BigDecimal forkResult = worker.forkResult(com); 384 System.out.println(forkResult); 385 } 386 }