下面用两种模式(masterWorker和guardedSuspension)的多线程地来实现1*1*1+2*2*2+...+100*100*100操作。
一、masterWorker
package com.exercise.masterWorker; import java.util.Map; import java.util.Set; public class Client { public static void main(String[] args) { Master m = new Master(new PlusWorker(),5);//5个线程 for (int i = 0; i < 100; i++) {//100个 任务 m.submit(i); } m.execute(); int re = 0; Map<String,Object> resultMap = m.getResultMap(); while(resultMap.size()>0 || !m.isComplete()){ System.out.println("resultMap.size()="+resultMap.size()); Set<String> keys = resultMap.keySet(); String key = null; for(String k:keys){ key = k; System.out.println("key="+key); break; } Integer i = null; if(key!=null){ i = (Integer) resultMap.get(key); } if(i!=null){ re+=i; } if(key!=null){ resultMap.remove(key); } } System.out.println("result="+re); } }
package com.exercise.masterWorker; import java.util.HashMap; import java.util.Map; import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; public class Master { protected Queue<Object> workQueue = new ConcurrentLinkedQueue<Object>(); protected Map<String,Thread> threadMap = new HashMap<String,Thread>(); protected Map<String,Object> resultMap = new ConcurrentHashMap<String,Object>(); public Master(Worker worker,int countWorker){ worker.setWorkQueue(workQueue); worker.setResultMap(resultMap); for (int i = 0; i < countWorker; i++) { threadMap.put(Integer.toString(i), new Thread(worker,Integer.toString(i))); } } public void submit(Object job){ workQueue.add(job); } public void execute(){ for(Map.Entry<String, Thread> entry : threadMap.entrySet()){ entry.getValue().start(); } } public Map<String,Object> getResultMap(){ return resultMap; } public boolean isComplete(){ for(Map.Entry<String, Thread> entry : threadMap.entrySet()){ if(entry.getValue().getState()!=Thread.State.TERMINATED){ return false; } } return true; } }
package com.exercise.masterWorker; import java.util.Map; import java.util.Queue; public class Worker implements Runnable{ protected Queue<Object> workQueue; protected Map<String,Object> resultMap; public Queue<Object> getWorkQueue() { return workQueue; } public void setWorkQueue(Queue<Object> workQueue) { this.workQueue = workQueue; } public Map<String, Object> getResultMap() { return resultMap; } public void setResultMap(Map<String, Object> resultMap) { this.resultMap = resultMap; } @Override public void run() { while(true){ Object input = workQueue.poll(); if(input==null) break; Object re = handle(input); resultMap.put(Integer.toString((Integer)input), re); } } public Object handle(Object input){ return input; } }
package com.exercise.masterWorker; public class PlusWorker extends Worker{ public Object handle(Object input){ Integer i = (Integer) input; return i*i*i; } }
package com.exercise.guardedSuspension; import java.util.ArrayList; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Client2 { public static void main(String[] args){ RequestQueue2 requestQueue2 = new RequestQueue2(); for (int i = 1; i <= 100; i++) { new ClientThread2(requestQueue2,i).start(); } int sum = 0; ExecutorService exec = Executors.newCachedThreadPool(); <span style="white-space:pre"> </span>ArrayList<Future<Integer>> results = new ArrayList<Future<Integer>>(); <span style="white-space:pre"> </span>for (int i = 1; i <= 100; i++) { <span style="white-space:pre"> </span>results.add(exec.submit(new ServerThread2(requestQueue2))); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>for (Future<Integer> future : results) { <span style="white-space:pre"> </span>try { sum+=future.get(); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>System.out.println("sum="+sum); <span style="white-space:pre"> </span>exec.shutdown(); } }
package com.exercise.guardedSuspension; import java.util.LinkedList; public class RequestQueue2 { private LinkedList queue2 = new LinkedList(); public synchronized Request2 getRequest2(){ while(queue2.size()==0){ try{ wait(); }catch(InterruptedException e){ } } return (Request2) queue2.remove(); } public synchronized void addRequest2(Request2 request2){ queue2.add(request2); notifyAll(); } }
package com.exercise.guardedSuspension; public class Request2 { private int num; private Data2 response; public int getNum() { return num; } public Request2(int num){ this.num=num; } public Data2 getResponse() { return response; } public void setResponse(Data2 response) { this.response = response; } }
package com.exercise.guardedSuspension; public class ClientThread2 extends Thread{ private int num; private RequestQueue2 requestQueue2; public ClientThread2(RequestQueue2 requestQueue2,int num){ this.requestQueue2 = requestQueue2; this.num = num; } public void run(){ Request2 request2 = new Request2(num); requestQueue2.addRequest2(request2); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } }
package com.exercise.guardedSuspension; import java.util.concurrent.Callable; public class ServerThread2 implements Callable<Integer>{ private RequestQueue2 requestQueue2; public ServerThread2(RequestQueue2 requestQueue2){ this.requestQueue2 = requestQueue2; } public Integer call() throws Exception { while(true){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } Request2 request2 = requestQueue2.getRequest2(); return request2.getNum()*request2.getNum()*request2.getNum(); } } }
package com.exercise.guardedSuspension; public class Request2 { private int num; public int getNum() { return num; } public Request2(int num){ this.num=num; } }