1.Future模式
说明:
例子:
//主函数
public class Main {
public static void main(String[] args) throws InterruptedException {
FutureClient fc = new FutureClient();
Data data = fc.request("请求参数");
System.out.println("请求发送成功!");
System.out.println("做其他的事情...");
String result = data.getRequest();
System.out.println(result);
}
}
//data接口
public interface Data {
String getRequest();
}
//2个实现了Data接口的类
public class FutureData implements Data{
private RealData realData ;
private boolean isReady = false;
public synchronized void setRealData(RealData realData) {
//如果已经装载完毕了,就直接返回
if(isReady){
return;
}
//如果没装载,进行装载真实对象
this.realData = realData;
isReady = true;
//进行通知
notify();
}
@Override
public synchronized String getRequest() {
//如果没装载好 程序就一直处于阻塞状态
while(!isReady){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//装载好直接获取数据即可
return this.realData.getRequest();
}
}
public class RealData implements Data{
private String result ;
public RealData (String queryStr){
System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result = "查询结果";
}
@Override
public String getRequest() {
return result;
}
}
//另起线程去做事
public class FutureClient {
public Data request(final String queryStr){
//1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
final FutureData futureData = new FutureData();
//2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
new Thread(new Runnable() {
@Override
public void run() {
//3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}
}).start();
return futureData;
}
}
输出结果:
请求发送成功!
做其他的事情...
根据请求参数进行查询,这是一个很耗时的操作..
操作完毕,获取结果
查询结果
2.master-worker模式
例子:
public class Master {
//1,应该有一个承装任务的集合
private ConcurrentLinkedQueue<Task> taskQueue= new ConcurrentLinkedQueue<Task>();
//2 需要有一个盛放worker的集合
private HashMap<String, Thread> workers = new HashMap<String, Thread>();
//3 需要有一个盛放每一个worker执行任务的结果集合
private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<String, Object> ();
//4.构造方法 放work
public Master(Worker worker,int workCount){
//每个worker对象要有taskQueue的引用,用于取任务
//resultMap用于任务的提交
worker.setTaskQueue(taskQueue);
worker.setResultMap(resultMap);
for (int i = 0; i <workCount ; i++) {
//key表示worker的名字,value表示线程执行对象
workers.put("work"+i,new Thread(worker));
}
}
//5.提交方法,用于往队列里面添加任务
public void submit(Task task){
this.taskQueue.add(task);
}
//6.需要有一个执行的方法,让所有的worker去执行任务task
public void execute(){
for(Map.Entry<String,Thread> me : workers.entrySet()){
me.getValue().start();
}
}
//7判断线程是否都执行完
public boolean isComplete() {
for(Map.Entry<String,Thread> me : workers.entrySet()){
if (me.getValue().getState()!=Thread.State.TERMINATED){
return false;
}
}
return true;
}
//8.返回结果集
public int getResult(){
int ret=0;
for(Map.Entry<String,Object> me : resultMap.entrySet()){
ret+= (Integer)me.getValue();
}
return ret;
}
//任务类
public class Task {
private int id;
private String name;
private int price ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
//work类 执行任务
public class Worker implements Runnable {
private ConcurrentLinkedQueue<Task> taskQueue;
private ConcurrentHashMap<String, Object> resultMap ;
public void setTaskQueue(ConcurrentLinkedQueue<Task> taskQueue) {
this.taskQueue = taskQueue;
}
public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap = resultMap;
}
@Override
public void run() {
while (true){
//取出元素并且移除
Task input = this.taskQueue.poll();
if (input==null) break ;
//真正的去处理业务
Object output = handle(input);
this.resultMap.put(Integer.toString(input.getId()),output);
}
}
private Object handle(Task input) {
Object output=null;
try {
//模拟处理task的时间
Thread.sleep(1000);
output= input.getPrice();
} catch (InterruptedException e) {
e.printStackTrace();
}
return output;
}
}
//主函数
public class Main {
public static void main(String[] args) {
//20个处理器
Master master= new Master(new Worker(), 20);
Random random = new Random();
//100个任务
for (int i = 1; i <=100 ; i++) {
Task task= new Task();
task.setId(i);
task.setName("任务"+i);
task.setPrice(random.nextInt(1000));
master.submit(task);
}
//执行 让10个work去取任务
master.execute();
long start = System.currentTimeMillis();
//判断任务是否都执行完了
while (true){
if (master.isComplete()){
int result = master.getResult();
System.out.println("结果为:"+result+"执行时间:"+(System.currentTimeMillis()-start)+"毫秒");
break;
}
}
}
}
//运行结果:
结果为:50643执行时间:5006毫秒
改变Worker的个数,时间会不一样
说明:这个例子比较简单。。
100个任务放在了 ConcurrentLinkedQueue 里面
每个worker线程用于处理任务,这里新建了20个work,HashMap<String, Thread>用于存放work。
ConcurrentHashMap<String, Object>用于放处理之后的结果集,之所以用ConcurrentHashMap,是因为20个线程并发放map里面放东西。
循环装work的map用Thread.State.TERMINATED判断线程状态是否终止。
用sleep模仿每个线程执行1秒,100个任务100秒,20个线程去跑,每个线程大约5秒符合