例子场景 :有多个Person,每个person计算出自己属性的A到B之间的整数的和
1.先导入相关的jar包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>disruptor</groupId>
<artifactId>disruptor</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>disruptor Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.1.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
</dependencies>
<build>
<finalName>disruptor</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<plugin>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-maven-plugin</artifactId>
<version>1.12.6.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
2.数据载体PersonEntity实体类
package com.demo;
/**
* @Description:
* @Author: Tgy
* @Date: 2019/12/20 18:21
**/
public class PersonEntity {
private String name;
private String address;
private int age;
private int a;
private int b;
public PersonEntity() {
}
public PersonEntity(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
public PersonEntity(String name, String address, int age, int a, int b) {
this.name = name;
this.address = address;
this.age = age;
this.a = a;
this.b = b;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
}
3.事件工厂
package com.demo;
/**
* 事件工厂
*/
public class EventFactory implements com.lmax.disruptor.EventFactory<PersonEntity> {
@Override
public PersonEntity newInstance() {
return new PersonEntity();
}
}
4.消费者
package com.demo;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
import java.util.concurrent.ForkJoinPool;
/**
* @Description: 处理每个传进来的PersonEntity
* @Author: Tgy
* @Date: 2019/12/20 18:40
**/
public class PersonConsumer implements EventHandler<PersonEntity>, WorkHandler<PersonEntity> {
@Override
public void onEvent(PersonEntity personEntity, long l, boolean b) throws Exception {
}
@Override
public void onEvent(PersonEntity personEntity) throws Exception {
dealData( personEntity);
}
private String reward;
public PersonConsumer(String reward) {
this.reward=reward;
}
public void dealData(PersonEntity personEntity){
System.out.println(personEntity.getName()+"算出了 "+personEntity.getA()+"——>"+personEntity.getB()+" 的和:"+getResut(personEntity.getA(),personEntity.getB())+", 奖励:"+reward);
}
private int getResut(int a,int b){
if(a>b){
return 0;
}else {
int result=0;
for(int i=a;i<b+1;i++){
result=result+i;
}
return result;
}
}
}
5.数据产生和生产者
package com.demo;
import com.lmax.disruptor.BlockingWaitStrategy;
import com.lmax.disruptor.EventTranslator;
import com.lmax.disruptor.RingBuffer;
import com.lmax.disruptor.dsl.Disruptor;
import com.lmax.disruptor.dsl.ProducerType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
/**
* @Description: Disruptor例子
* @Author: Tgy
* @Date: 2019/12/20 18:12
*
* PersonEntity:消费者消费的数据载体
*让每个消费者算出对应的a到b之间的数字的和
**/
@Slf4j
public class DoMain {
public static void main(String[] args) {
//需要处理的数据
List<PersonEntity> pList=new ArrayList<>();
pList.add(new PersonEntity("小红","深圳",23,2,60));
pList.add(new PersonEntity("小明","广州",52,30,100));
pList.add(new PersonEntity("小黄","上海",30,66,90));
pList.add(new PersonEntity("彤彤","东莞",50,11,30));
pList.add(new PersonEntity("阿尔法","福州",66,40,60));
pList.add(new PersonEntity("贝塔","梅州",18,60,80));
pList.add(new PersonEntity("乔治","潮汕",13,20,32));
ThreadFactory producerFactory = Executors.defaultThreadFactory();
// 创建一个Trans工厂对象
EventFactory eventFactory = new EventFactory();
// RingBuffer 缓冲区的长度 2的倍数
int bufferSize = 1024;
Disruptor<PersonEntity> disruptor = new Disruptor(eventFactory, bufferSize, producerFactory, ProducerType.SINGLE, new BlockingWaitStrategy());
int threadNum = Runtime.getRuntime().availableProcessors() / 2;
log.info("开始启动{}个线程处理数据", threadNum);
// PersonConsumer[] personConsumers = new PersonConsumer[3];//消费者,单线程
// for(int i = 0;i < personConsumers.length; i++){
// personConsumers[i] = new PersonConsumer("奖励一朵花");//消费者通过构造方法接收参数
// }
// disruptor.handleEventsWithWorkerPool(personConsumers);
PersonConsumer1[] personConsumers1 = new PersonConsumer1[3];//消费者,多线程
for(int i = 0;i < personConsumers1.length; i++){
personConsumers1[i] = new PersonConsumer1("奖励一颗星");//消费者通过构造方法接收参数
}
// handleEventsWithWorkerPool 不会重复消费消息. handleEventsWith会重复消费
disruptor.handleEventsWithWorkerPool(personConsumers1);
// 启动
disruptor.start();
// 获取到RingBuffer
RingBuffer<PersonEntity> ringBuffer = disruptor.getRingBuffer();
final ByteBuffer byteBuffer = ByteBuffer.allocate(8);
// 向RingBuffer添加数据
for(final PersonEntity personEntity : pList){
ringBuffer.publishEvent(new EventTranslator<PersonEntity>() {
@Override
public void translateTo(PersonEntity event, long sequence) {//生产者-->往RingBuffer里面塞数据
BeanUtils.copyProperties(personEntity, event);
}
});
}
disruptor.shutdown();//关闭disruptor,方法会堵塞,直至所有的事件都得到处理
System.out.println("处理完成了----------->");//因为关闭disruptor,此输出会在所有的事件都得到处理后执行
}
}
以上就是disruptor的简单应用
拓展:消费者可以用多线程 处理
场景:每个线程处理A到B之间的十个数字以内的数字的和
package com.demo;
import com.lmax.disruptor.EventHandler;
import com.lmax.disruptor.WorkHandler;
import java.util.concurrent.ForkJoinPool;
/**
* @Description: 处理每个传进来的PersonEntity
* @Author: Tgy
* @Date: 2019/12/20 18:40
* 多线程处理PersonEntiyt:每个线程处理a-->b之间的十个数字的和
**/
public class PersonConsumer1 implements EventHandler<PersonEntity>, WorkHandler<PersonEntity> {
// forkjoin 线程池.最大并发数10
private static ForkJoinPool pool = new ForkJoinPool(10);
@Override
public void onEvent(PersonEntity personEntity, long l, boolean b) {
}
@Override
public void onEvent(PersonEntity personEntity) {
dealData( personEntity);
}
private String reward;
public PersonConsumer1(String reward) {
this.reward=reward;
}
public void dealData(PersonEntity personEntity){
CalculationTask calculationTask = new CalculationTask(personEntity.getA(),personEntity.getB());
pool.invoke(calculationTask);
Integer taskResult=calculationTask.join();
System.out.println(personEntity.getName()+"算出了 "+personEntity.getA()+"——>"+personEntity.getB()+" 的和:"+taskResult+", 奖励:"+reward);
}
}
package com.demo;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.RecursiveTask;
/**
* @Description:计算两个数之间的数字的和
* @Author: Tgy
* @Date: 2019/12/23 13:53
**/
public class CalculationTask extends RecursiveTask<Integer> {
// 阈值。当数据长度大于或等于这个值时开启分任务
// 这里是让真正计算的时候,每两个参数之间的跨度少于10
private static final Integer THRESHOLD = 10;
private int a;
private int b;
public CalculationTask() {
}
public CalculationTask(int a, int b) {
this.a = a;
this.b = b;
}
@Override
protected Integer compute() {
if(a>b){
return 0;
}
//分割成区间在十个数以内的区间,再进行加法运算
int dataSize=b-a;
if(THRESHOLD<=dataSize){
CalculationTask calculationTask1 = new CalculationTask(a,a+(b-a)/2-1);
CalculationTask calculationTask2 = new CalculationTask(a+(b-a)/2,b);
invokeAll(calculationTask1, calculationTask2);
Integer result=calculationTask1.join()+calculationTask2.join();
return result;
}else {
int result=0;
for(int i=a;i<b+1;i++){
result=result+i;
}
return result;
}
}
}