disruptor使用的简单例子

例子场景 :有多个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;
        }
    }


}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值