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结 ...
随机推荐
- UOJ46. 【清华集训2014】玄学 [线段树,二进制分组]
UOJ 思路 模拟赛出了这题,结果我没学过二进制分组--一波主席树然后空间就爆炸了-- 用线段树维护时间序列,每个节点维护\(a_i\to x_i\times a_i+b_i,i\in [1,n]\) ...
- 框架 get 请求乱码
解决方案: 在 tomcat 配置文件中添加 URIEncoding="utf-8"
- 现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为buyer_favorite1。 buyer_favorite1包含:买家id,商品id,收藏日期这三个字段,数据以“\t”分割
实验内容(mapReduce安装请按照林子雨教程http://dblab.xmu.edu.cn/blog/631-2/) 现有某电商网站用户对商品的收藏数据,记录了用户收藏的商品id以及收藏日期,名为 ...
- Hadoop(二)—— HDFS
HDFS(Hadoop Distributed File System)Hadoop分布式文件系统. 一.HDFS产生的背景 随着数据量越来越大,如果大到一台主机的磁盘都存放不下,该如何解决这个问题. ...
- socket http tcp ip 区别联系
功能是实现继承复用.刚才做了一个简要的概述,里面有一些常用的概念,这里做个简短的概念普及介绍:(1),TCP/IP------TPC/IP协议是传输层协议,主要解决数据如何在网络中传输.(2),Soc ...
- 使用lombok的@Builder的注解的一个坑
一开发说项目报错 java.lang.Long,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lan ...
- 从ReentrantLock的实现看AQS的原理及应用 可重入锁
https://mp.weixin.qq.com/s/sA01gxC4EbgypCsQt5pVog
- [转]eclipse中 properties文件编码问题
原文地址:https://blog.csdn.net/uestcong/article/details/6635123 1. Eclipse修改设置项目中用到了配置文件,所以在Eclipse中新建.p ...
- 爬虫中BeautifulSoup4解析器
CSS 选择器:BeautifulSoup4 和 lxml 一样,Beautiful Soup 也是一个HTML/XML的解析器,主要的功能也是如何解析和提取 HTML/XML 数据. lxml 只会 ...
- fiddler 捕捉不到代码发出去的HTTP请求
检查代码里是不是把代理设置为空了,null. 或是通过.config文件禁用了代理.