Java多线程之主从设计模式-yellowcong
来源:互联网 发布:unity3d htc vive开发 编辑:程序博客网 时间:2024/05/21 08:59
在Hadoop和Redis等集群的时候,都会有主从的概念,有一个主节点用于控制请求的分发和结果的统计,从节点用于真正的数据处理操作。在多线程中,我们可以把 一个大任务分割成多个小任务,给子节点处理,在这种设计模式中,我们需要使用到原子类 ConcurrentLinkedQueue (用于存储请求提交的任务),和ConcurrentHashMap(用于收集每一个节点获取的结果)。在这种无锁的设计模式中,必须用到原子类的对象,解决数据的统一问题
在多线程开发中,需要多使用原子类解决问题,而不是使用锁的方式来解决,锁的方式效率相对比较低,notify和wait方式远不及Lock类的锁,所以开发中,能使用到原子类的,尽量用原子类完成。
任务对象
任物对象,只是一个简单的java bean,没有任何的复杂处理,这个案例设计的是,有一个加法运算,分成多个任务,通过Work线程完成
package com.yellowcong.work;/** * 创建日期:2017年10月6日 <br/> * 创建用户:yellowcong <br/> * 功能描述:任务队列 */public class Task { private String name; private String id; private Integer price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; }}
Master类
主对象中,必须有三个重要的对象
1、ConcurrentLinkedQueue<Task>
,收集任务队列,将所有提交的任务都会放到这个队列中
2、HashMap<String, Thread>
来维护 Master管理的Work对象(任务处理节点,判断主节点可以管理多少个小弟完成人物),在添加任务后,可以遍历这个对象的线程,启动Work任务
3、ConcurrentHashMap<String, Object>
用于收集每个Work节点处理的结果,然后在主节点中做统计处理
package com.yellowcong.work;import java.security.KeyStore.Entry;import java.util.HashMap;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;/** * 创建日期:2017年10月6日 <br/> * 创建用户:yellowcong <br/> * 功能描述: */public class Master { //1.任务管理 private ConcurrentLinkedQueue<Task> tasks = new ConcurrentLinkedQueue<Task>(); //2.master来管理的Works private HashMap<String, Thread> works = new HashMap<String, Thread>(); //3.用这个容器来接收处理 完成的任务的结果集 private ConcurrentHashMap<String, Object> results = new ConcurrentHashMap<String, Object>(); //4、设定人物和启动的线程数量 public Master(Work work,int count) { //每个work里面需要有 放result和获取人物的队列 work.setResults(results); work.setTasks(tasks); //将多个线程的Work都放到HashMap集合中 for(int i=0;i<count;i++){ //key 是节点的名字, val是多线程 works.put(String.valueOf(i),new Thread(work)); } } //5、提交任务 public void submit(Task task){ this.tasks.add(task); } //6、启动任务 public void execute(){ for(Map.Entry<String, Thread> entry :works.entrySet()){ //启动所有线程 entry.getValue().start(); } } //7.判断线程是否完毕 public boolean isComplite(){ for(Map.Entry<String, Thread> entry :works.entrySet()){ // 线程执行完毕或异常退出会进入终止状态 ,判断是否是终止状态 if(entry.getValue().getState() != Thread.State.TERMINATED){ return false; } } return true; } //8.返回结果数据 public long getResult(){ long data = 0l; for(Map.Entry<String, Object> entry :results.entrySet()){ data += Long.parseLong(String.valueOf(entry.getValue().toString())); } return data; }}
Work 类
这个类实现了Runable接口,在这个里面,有 ConcurrentHashMap<String, Object>
ConcurrentLinkedQueue<Task>
这两个集合对象,是由Master传递过来,目的 是为了获取任务和将任务处理的结果存储起来
package com.yellowcong.work;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.ConcurrentLinkedQueue;/** * 创建日期:2017年10月6日 <br/> * 创建用户:yellowcong <br/> * 功能描述:Master所管理的类,Master的人物都分派给Work做 */public class Work implements Runnable { private ConcurrentHashMap<String, Object> results; private ConcurrentLinkedQueue<Task> tasks; public void setResults(ConcurrentHashMap<String, Object> results) { this.results = results; } public void setTasks(ConcurrentLinkedQueue<Task> tasks) { this.tasks = tasks; } public void run() { while(true){ //当任务为空的情况 if(tasks.isEmpty()){ break; } //获取一个任务 Task task = this.tasks.poll(); Object result = haddle(task); //设定结果 this.results.put(task.getId(), result); } } /** * 真正处理事情的逻辑 * 创建日期:2017年10月6日<br/> * 创建用户:yellowcong<br/> * 功能描述: * @param task * @return */ private Object haddle(Task task) { try { Thread.sleep(500); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } return task.getPrice(); }}
测试类
测试类中,启动了10个 Work对象,来完成整个任务,当线程数量增加时,整体锁用的时间,就会减少。
package com.yellowcong.work;import java.util.Random;/** * 创建日期:2017年10月6日 <br/> * 创建用户:yellowcong <br/> * 功能描述: */public class MainTest { public static void main(String[] args) { System.out.println(Thread.activeCount()); //建立一个主节点 Master master = new Master(new Work(), 10); Random rand = new Random(); for(int i=0;i<100;i++){ Task task = new Task(); task.setId(String.valueOf(i)); task.setName("任务"+i); task.setPrice(rand.nextInt(1000)); //提交任务 master.submit(task); } //执行任务 long start = System.currentTimeMillis(); master.execute(); //判断是否执行完成 while(true){ if(master.isComplite()){ long result = master.getResult(); long end = System.currentTimeMillis(); System.out.println("最终结果"+result+",耗时"+Long.toString(end-start)); break; } } }}
- Java多线程之主从设计模式-yellowcong
- Java多线程之单例模式-yellowcong
- Java多线程之队列Quene-yellowcong
- Java多线程之CyclicBarrier用法-yellowcong
- Java多线程之Semaphore用法-yellowcong
- Java多线程之ReentrantLock使用-yellowcong
- Mysql之主从复制-yellowcong
- java多线程设计模式之-SingleThreadExecution模式
- Java多线程设计模式之Immutable模式
- java多线程设计模式之GuardSuspension模式
- Java多线程设计模式之Promise 模式
- java 多线程设计模式之future
- java多线程设计模式之Immutable Pattern
- java多线程设计模式之Guarded Suspension
- Java 多线程的设计模式之 Future
- Java 多线程设计模式之Guarded Suspension
- Java 多线程设计模式之Producer-Consumer
- ActiveMQ之集群(主从)搭建-yellowcong
- LeetCode-91-Decode Ways DP
- Codeforces Round #438 A+B+C Contest 868
- spark Streaming flume poll 坑
- Ubuntu系统安装Ruby的三种方法
- VR和AR
- Java多线程之主从设计模式-yellowcong
- thinkphp 集成swagger-php
- 10-06 DFS学习——经典例题之八皇后
- Java集合类总结
- linux学习笔记 day1
- vector删除元素
- 171005 逆向-IAT导入地址表
- 技术与技术人员的价值
- 10-06 DFS学习——经典例题之数独(题目转自洛谷华南师大附中团队邀请赛,未ac,90分)