多线程设计模式之Future、Master-Worker和生产者-消费者模型

  并行设计模式属于设计优化的一部分,它是对一些常用的多线程结构的总结和抽象。与串行程序相比,并行程序的结构通常更为复杂。因此合理的使用并行模式在开发中更有意义,目前在开发中应用最多的是Future,Master-Woker和生产者-消费者模式
一、Future模式
  流程图如下
在这里插入图片描述

public interface Data {

	String 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 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 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;
	}
	
}
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);
		
	}
}

一、Master-Woker模式
  Master-Woker模式是常用的并行计算模式。它的核心思想是系统由两类进程协作工作:Master进程Worker进程。Master负责接收和分配任务,Worker负责处理子任务。当各个子进程处理完成之后,会将结果返回给Master,由Master做归纳和总结。好处是能够将一个大任务分解成若干个小任务,并执行,从而提高系统的吞吐量。
在这里插入图片描述

public class Master_Join {
    // 1 有一个盛放任务的容器
    private ConcurrentLinkedQueue<Task> workQuen = new ConcurrentLinkedQueue<>();

    // 2 需要一个盛放worker的集合
    private Map<String,Thread> workers = new HashMap<String,Thread>();

    // 3 需要有一个盛放每一个worker执行任务的结果集合
    private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<>();

    // 4 构造方法

    public Master_Join( Worker worker,int workerCount ){
         worker.setWorkQuen(this.workQuen);
         worker.setResultMap(this.resultMap);
        for (int i = 0; i < workerCount; i++) {
            this.workers.put(Integer.toString(i),new Thread(worker));

        }
    }
    // 5 需要一个提交任务的方法
    public void submit(Task task){
        this.workQuen.add(task);
    }
    // 6 需要有一个执行任务的方法,启动所有的worker的方法并且执行
    public void execute(){
        for ( Map.Entry<String,Thread> worker :  workers.entrySet()){
                worker.getValue().start();
        }

    }
    // 7 判断是否运行结束的方法
    public boolean isComplete(){
        for ( Map.Entry<String,Thread> worker :  workers.entrySet()){
           if(worker.getValue().getState() != Thread.State.TERMINATED){
               return  false;
           }
        }
        return  true;
    }

    // 8 获得计算结果的方法
    public Double getResult(){
        Double priceResult = 0d;
        for(Map.Entry<String,Object> map : resultMap.entrySet()){
            priceResult +=(Double) map.getValue();
        }
        return priceResult;
    }

}
public class Task {
    private Long id;
    private String name;
    private double price;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}
public class Worker implements Runnable{
    private ConcurrentLinkedQueue<Task> workQuen;
    private ConcurrentHashMap<String,Object> resultMap;

    public void setWorkQuen(ConcurrentLinkedQueue<Task> workQuen) {
        this.workQuen = workQuen;
    }

    public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
        this.resultMap = resultMap;
    }


    @Override
    public void run() {
        while (true){
            Task input = this.workQuen.poll();
            if(null == input){
                break;
            }
            Object output = handle(input);
            this.resultMap.put(Long.toString(input.getId()),output);
        }
        

    }

    private Object handle(Task input) {
      return null;
    }

   /* private Object handle(Task input) {
        Object output = null;
        try {
            // 处理任务耗时。。。
            Thread.sleep(300);
            output = input.getPrice();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  output ;
    }*/

public class MyWorker  extends  Worker{
    private Object handle(Task input) {
        Object output = null;
        try {
            // 处理任务耗时。。。
            Thread.sleep(300);
            output = input.getPrice();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  output ;
    }
}
public class Main {
    public static void main(String[] args) {

        Master_Join master = new Master_Join(new Worker(),20);
        Random random  = new Random();

        for(long i = 0; i < 100; i++){
            Task task = new Task();
            task.setId(i);
            task.setPrice(random.nextInt(1500));
            master.submit(task);
        }

        master.execute();

        Instant instant = Instant.now();
        while (true){
            if(master.isComplete()){
                Instant  instant1 = Instant.now();
                Double result = master.getResult();
                long seconds = Duration.between(instant1, instant).getNano();
                System.out.println("最终结果:"+result+ "耗时:"+ seconds);
                break;
            }
        }


    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值