JAVA线程Disruptor核心链路应用(八)







import java.util.concurrent.atomic.AtomicInteger; /**
* Disruptor中的 Event
* @author Alienware
*
*/
public class Trade { private String id;
private String name;
private double price;
//在并发时实现线程安全
private AtomicInteger count = new AtomicInteger(0); public Trade() {
}
public String getId() {
return id;
}
public void setId(String 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 AtomicInteger getCount() {
return count;
}
public void setCount(AtomicInteger count) {
this.count = count;
}
}
import java.util.Random;
import java.util.concurrent.CountDownLatch; import com.lmax.disruptor.EventTranslator;
import com.lmax.disruptor.dsl.Disruptor; public class TradePushlisher implements Runnable { private Disruptor<Trade> disruptor;
private CountDownLatch latch; private static int PUBLISH_COUNT = 1; public TradePushlisher(CountDownLatch latch, Disruptor<Trade> disruptor) {
this.disruptor = disruptor;
this.latch = latch;
} public void run() {
TradeEventTranslator eventTranslator = new TradeEventTranslator();
for(int i =0; i < PUBLISH_COUNT; i ++){
//新的提交任务的方式
disruptor.publishEvent(eventTranslator);
}
latch.countDown();
}
} class TradeEventTranslator implements EventTranslator<Trade> { private Random random = new Random(); public void translateTo(Trade event, long sequence) {
this.generateTrade(event);
} private void generateTrade(Trade event) {
event.setPrice(random.nextDouble() * 9999);
}
}
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler; public class Handler1 implements EventHandler<Trade>, WorkHandler<Trade>{ //EventHandler
public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
this.onEvent(event);
} //WorkHandler
public void onEvent(Trade event) throws Exception {
System.err.println("handler 1 : SET NAME");
Thread.sleep(1000);
event.setName("H1");
}
}
import java.util.UUID;
import com.lmax.disruptor.EventHandler; public class Handler2 implements EventHandler<Trade> { public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
System.err.println("handler 2 : SET ID");
Thread.sleep(2000);
event.setId(UUID.randomUUID().toString());
}
}
import com.lmax.disruptor.EventHandler;
public class Handler3 implements EventHandler<Trade> {
public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
System.err.println("handler 3 : NAME: "
+ event.getName()
+ ", ID: "
+ event.getId()
+ ", PRICE: "
+ event.getPrice()
+ " INSTANCE : " + event.toString());
}
}
import com.lmax.disruptor.EventHandler;
public class Handler4 implements EventHandler<Trade> {
public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
System.err.println("handler 4 : SET PRICE");
Thread.sleep(1000);
event.setPrice(17.0);
}
}
import com.lmax.disruptor.EventHandler;
public class Handler5 implements EventHandler<Trade> {
public void onEvent(Trade event, long sequence, boolean endOfBatch) throws Exception {
System.err.println("handler 5 : GET PRICE: " + event.getPrice());
Thread.sleep(1000);
event.setPrice(event.getPrice() + 3.0);
}
}
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import com.lmax.disruptor.BusySpinWaitStrategy;
import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.EventHandlerGroup;
import com.lmax.disruptor.dsl.ProducerType; public class Main {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception { //构建一个线程池用于提交任务
ExecutorService es1 = Executors.newFixedThreadPool(1); ExecutorService es2 = Executors.newFixedThreadPool(5);
//1 构建Disruptor
Disruptor<Trade> disruptor = new Disruptor<Trade>(
new EventFactory<Trade>() {
public Trade newInstance() {
return new Trade();
}
},
1024*1024,
es2,
ProducerType.SINGLE,
new BusySpinWaitStrategy()); //2 把消费者设置到Disruptor中 handleEventsWith //2.1 串行操作: disruptor
.handleEventsWith(new Handler1())
.handleEventsWith(new Handler2())
.handleEventsWith(new Handler3()); //2.2 并行操作: 可以有两种方式去进行
//1 handleEventsWith方法 添加多个handler实现即可
//2 handleEventsWith方法 分别进行调用 disruptor.handleEventsWith(new Handler1(), new Handler2(), new Handler3());
disruptor.handleEventsWith(new Handler2());
disruptor.handleEventsWith(new Handler3()); //2.3 菱形操作 (一) disruptor.handleEventsWith(new Handler1(), new Handler2())
.handleEventsWith(new Handler3()); //2.3 菱形操作 (二) EventHandlerGroup<Trade> ehGroup = disruptor.handleEventsWith(new Handler1(), new Handler2());
ehGroup.then(new Handler3()); //2.4 六边形操作
Handler1 h1 = new Handler1();
Handler2 h2 = new Handler2();
Handler3 h3 = new Handler3();
Handler4 h4 = new Handler4();
Handler5 h5 = new Handler5();
disruptor.handleEventsWith(h1, h4);
disruptor.after(h1).handleEventsWith(h2);
disruptor.after(h4).handleEventsWith(h5);
disruptor.after(h2, h5).handleEventsWith(h3); //3 启动disruptor
RingBuffer<Trade> ringBuffer = disruptor.start(); //设置唤醒的次数
CountDownLatch latch = new CountDownLatch(1); long begin = System.currentTimeMillis(); es1.submit(new TradePushlisher(latch, disruptor)); latch.await(); //进行向下 disruptor.shutdown();
es1.shutdown();
es2.shutdown();
System.err.println("总耗时: " + (System.currentTimeMillis() - begin)); }
}
多生产者模型:

多消费者:


import java.util.concurrent.atomic.AtomicInteger;
public class Order {
private String id;
private String name;
private double price;
public Order() {
}
public String getId() {
return id;
}
public void setId(String 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;
}
}
import com.lmax.disruptor.RingBuffer;
public class Producer {
private RingBuffer<Order> ringBuffer;
public Producer(RingBuffer<Order> ringBuffer) {
this.ringBuffer = ringBuffer;
}
public void sendData(String uuid) {
long sequence = ringBuffer.next();
try {
Order order = ringBuffer.get(sequence);
order.setId(uuid);
} finally {
ringBuffer.publish(sequence);
}
}
}
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger; import com.lmax.disruptor.WorkHandler; //消费者实现多消费的接口
public class Consumer implements WorkHandler<Order> { private String comsumerId; private static AtomicInteger count = new AtomicInteger(0); private Random random = new Random(); public Consumer(String comsumerId) {
this.comsumerId = comsumerId;
} public void onEvent(Order event) throws Exception {
Thread.sleep(1 * random.nextInt(5));
System.err.println("当前消费者: " + this.comsumerId + ", 消费信息ID: " + event.getId());
count.incrementAndGet();
} public int getCount(){
return count.get();
}
}
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors; import com.lmax.disruptor.EventFactory;
import com.lmax.disruptor.ExceptionHandler;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.SequenceBarrier;
import com.lmax.disruptor.WorkerPool;
import com.lmax.disruptor.YieldingWaitStrategy;
import com.lmax.disruptor.dsl.ProducerType; public class Main { //1 创建RingBuffer
RingBuffer<Order> ringBuffer =
RingBuffer.create(ProducerType.MULTI,
new EventFactory<Order>() {
public Order newInstance() {
return new Order();
}
},
1024*1024,
new YieldingWaitStrategy()); //2 通过ringBuffer 创建一个屏障
SequenceBarrier sequenceBarrier = ringBuffer.newBarrier(); //3 创建多个消费者数组:
Consumer[] consumers = new Consumer[10];
for(int i = 0; i < consumers.length; i++) {
consumers[i] = new Consumer("C" + i);
} //4 构建多消费者工作池
WorkerPool<Order> workerPool = new WorkerPool<Order>(
ringBuffer,
sequenceBarrier,
new EventExceptionHandler(), //在失败的时候怎么处理
consumers); //5 设置多个消费者的sequence序号 用于单独统计消费进度, 并且设置到ringbuffer中
ringBuffer.addGatingSequences(workerPool.getWorkerSequences()); //6 启动workerPool
workerPool
.start(Executors.newFixedThreadPool(5)); final CountDownLatch latch = new CountDownLatch(1); for(int i = 0; i < 100; i++) {
final Producer producer = new Producer(ringBuffer);
new Thread(new Runnable() {
public void run() {
try {
latch.await();
} catch (Exception e) {
e.printStackTrace();
}
for(int j = 0; j<100; j++) {
producer.sendData(UUID.randomUUID().toString());
}
}
}).start();
} Thread.sleep(2000);
System.err.println("----------线程创建完毕,开始生产数据----------");
latch.countDown(); Thread.sleep(10000); System.err.println("任务总数:" + consumers[2].getCount());
} static class EventExceptionHandler implements ExceptionHandler<Order> {
@Override
public void handleEventException(Throwable ex, long sequence, Order event) {
}
@Override
public void handleOnStartException(Throwable ex) {
}
@Override
public void handleOnShutdownException(Throwable ex) {
}
}
}
















读读共享、读写互斥、写写互斥


LockSupport :
Thread A = new Thread(new Runnable() {
@Override
public void run() {
int sum = 0;
for(int i =0; i < 10; i ++){
sum += i;
}
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LockSupport.park(); //后执行
System.err.println("sum: " + sum);
}
});
A.start();
Thread.sleep(1000);
LockSupport.unpark(A); //先执行
Executors.newCachedThreadPool();
Executors.newFixedThreadPool(10);
ThreadPoolExecutor pool = new ThreadPoolExecutor(5,
Runtime.getRuntime().availableProcessors() * 2,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(200),
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setName("order-thread");
if(t.isDaemon()) {
t.setDaemon(false);
}
if(Thread.NORM_PRIORITY != t.getPriority()) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
},
new RejectedExecutionHandler() {
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.err.println("拒绝策略:" + r);
}
});
ReentrantLock reentrantLock = new ReentrantLock(true);
线程池:
ThreadPoolExecutor pool=new ThreadPoolExecutor(
5,
Runtime.getRuntime().availableProcessors()*2,
60,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(200),
new ThreadFactory() { @Override
public Thread newThread(Runnable r) {
Thread thread=new Thread(r);
thread.setName("order-thread");
if(thread.isDaemon()){
thread.setDaemon(false);
}
if(Thread.NORM_PRIORITY!=thread.getPriority()){
thread.setPriority(Thread.NORM_PRIORITY);
}
return thread;
}
},
new RejectedExecutionHandler() { @Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
System.err.println("拒绝策略:"+r);
}
});
AQS架构:















JAVA线程Disruptor核心链路应用(八)的更多相关文章
- disruptor 核心链路应用场景
核心链路一般比较复杂并且需要考虑:服务之间相互依赖性.流程能够走完.人员的变动等情况 要考虑:兜底.补偿. 常见解决方案是:1)完全解耦 2)模板模式 其他解决方案:1)有限状态机框架:spring- ...
- Java并发编程:Java线程池核心ThreadPoolExecutor的使用和原理分析
目录 引出线程池 Executor框架 ThreadPoolExecutor详解 构造函数 重要的变量 线程池执行流程 任务队列workQueue 任务拒绝策略 线程池的关闭 ThreadPoolEx ...
- Java线程池核心原理剖析
在系统开发时,我们经常会遇到“池”的概念.使用池一种以空间换时间的做法,通常在内存中事先保存一系列整装待命的对象,以供后期供其他对象随时调用.常见的池有:数据库连接池,socket连接池,线程池等.今 ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- 关于CPU核心,线程,进程,并发,并行,及java线程之间的关系
前言:作为一个转行java的小白,一直搞不清楚java中的多线程.于是来梳理一下关于CPU核心,线程,进程,并发,并行,及java线程之间的关系, 1.CPU角度来看: 我们以Intel的Core i ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- Java 线程池框架核心代码分析
前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和资源消耗都是很高的.线程池应运而生,成为我们管理线程的利器.Java 通过Executor接口,提供了一种标准的方法将任务的提交过 ...
- java线程池技术(二): 核心ThreadPoolExecutor介绍
版权声明:本文出自汪磊的博客,转载请务必注明出处. Java线程池技术属于比较"古老"而又比较基础的技术了,本篇博客主要作用是个人技术梳理,没什么新玩意. 一.Java线程池技术的 ...
- Netty核心概念(7)之Java线程池
1.前言 本章本来要讲解Netty的线程模型的,但是由于其是基于Java线程池设计而封装的,所以我们先详细学习一下Java中的线程池的设计.之前也说过Netty5被放弃的原因之一就是forkjoin结 ...
随机推荐
- 复旦高等代数 I(16级)每周一题
每周一题的说明 一.本学期高代I的每周一题面向16级的同学,将定期更新(一般每周的周末公布下一周的题目); 二.欢迎16级的同学通过微信或书面方式提供解答图片或纸质文件给我,优秀的解答可以分享给大家: ...
- Noip2019暑期训练2 反思
经过两次测试,通过深刻的反思,我主要发现了以下易犯错误: 1.做题目时过于追求速度,导致好几处代码都出现手误打错的现象!而且,千万不要图快.图方便就复制粘贴,非常容易出错!(例如T3-party中直接 ...
- win7安装composer Failed to decode zlib stream
今天学习php的时候想安装一下composer,刚开始采用的是exe文件的安装方式,可是安装了好几次都没有安装成功,如下图: 可能还有其他的一些错误,所以这里我就换了一个方式安装,就是自己手动来安装c ...
- 【算法编程 C++ Python】根据前序遍历、中序遍历重建二叉树
题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7, ...
- 【软工实践】Beta冲刺(5/5)
链接部分 队名:女生都队 组长博客: 博客链接 作业博客:博客链接 小组内容 恩泽(组长) 过去两天完成了哪些任务 描述 将数据分析以可视化形式展示出来 新增数据分析展示等功能API 服务器后端部署, ...
- echo * 和ls *之间的区别?
背景描述: 今天 一同事做入职考试,涉及到1题目,echo * 和ls *之间的区别,没有用过这个用法,再次记录下. 操作过程: 1.执行echo * [root@localhost ~]# echo ...
- Sword 第三方库介绍一
/* 获取字符编码 */ #include <stdio.h> #include <stdlib.h> /* calloc()函数头文件 */ #include <str ...
- SD-WAN基础---SD-WAN简单了解
一:推文(摘录.转载自) 关于SD-WAN,你不得不了解的10个常识 那些让人怦然心动的SD-WAN功能(上) 那些让人怦然心动的SD-WAN功能(中) 二:SD-WAN是什么 SD-WAN,即软件定 ...
- function的json对象转换字符串与字符串转换为对象的方法
// json对象转换成字符串var str = JSON.stringify(json, function(key, val) { if (typeof val === 'function') { ...
- [LeetCode] 543. Diameter of Binary Tree 二叉树的直径
Given a binary tree, you need to compute the length of the diameter of the tree. The diameter of a b ...