Java多線程(13) - Disruptor多線程併發框架進階多場景玩法、多生產者多消費者

多場景玩法

import java.util.Random;

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.EventHandler;

import com.lmax.disruptor.EventTranslator;

import com.lmax.disruptor.WorkHandler;

import com.lmax.disruptor.dsl.Disruptor;

import com.lmax.disruptor.dsl.ProducerType;

 

/**

 * 多場景玩法

 */

public class D03MultiScenario {

    public static void main(String[] args) throws InterruptedException {

        

         long start = System.currentTimeMillis();

        

         //線程池

         ExecutorService pool = Executors.newFixedThreadPool(5);

        

         //Disruptor

         Disruptor<MData> disruptor = new Disruptor<MData>(new EventFactory<MData>() {

             @Override

             public MData newInstance() {

                  return new MData();

             }

         }, 1024, pool,ProducerType.SINGLE,new BusySpinWaitStrategy());

        

         /*

          * P生產數據,C1C2執行完,纔到C3執行

          *  /C1\

          * P    C3

          *  \C2/

          */

//       EventHandlerGroup<MData> handleEventsWith = disruptor.handleEventsWith(new MDataConsumer1(),new MDataConsumer2());

//       handleEventsWith.then(new MDataConsumer3());

        

         //順序操作

//       disruptor.handleEventsWith(new MDataConsumer1()).

//                 handleEventsWith(new MDataConsumer2()).

//                 handleEventsWith(new MDataConsumer3());

        

         /*

          *  /C1 -> C4\

          * P          C3

          *  \C2 -> C5/

          */

//       MDataConsumer1 mDataConsumer1 = new MDataConsumer1();

//       MDataConsumer2 mDataConsumer2 = new MDataConsumer2();

//       MDataConsumer3 mDataConsumer3 = new MDataConsumer3();

//       MDataConsumer4 mDataConsumer4 = new MDataConsumer4();

//       MDataConsumer5 mDataConsumer5 = new MDataConsumer5();

//       disruptor.handleEventsWith(mDataConsumer1,mDataConsumer2);

//       disruptor.after(mDataConsumer1).handleEventsWith(mDataConsumer4);

//       disruptor.after(mDataConsumer2).handleEventsWith(mDataConsumer5);

//      disruptor.after(mDataConsumer4,mDataConsumer5).handleEventsWith(mDataConsumer3);

        

         //啓動

         disruptor.start();

        

         CountDownLatch countDownLatch = new CountDownLatch(1);

        

         //生產者

         pool.submit(new MDataProducer(disruptor,countDownLatch));

        

         //等待生產者完事

         countDownLatch.await();

        

         disruptor.shutdown();

         pool.shutdown();

         System.out.println("耗時:" + (System.currentTimeMillis() - start));

    }

}

/**

 * 數據

 */

class MData {

    private int id;

    private String value;

 

    public int getId() {

         return id;

    }

 

    public void setId(int id) {

         this.id = id;

    }

 

    public String getValue() {

         return value;

    }

 

    public void setValue(String value) {

         this.value = value;

    }

}

/**

 * 生產者

 */

class MDataProducer implements Runnable {

 

    private Disruptor<MData> disruptor;

    private CountDownLatch countDownLatch;

   

    public MDataProducer(Disruptor<MData> disruptor, CountDownLatch countDownLatch) {

         super();

         this.disruptor = disruptor;

         this.countDownLatch = countDownLatch;

    }

   

    @Override

    public void run() {

         //模擬百萬次訂單交易

         for (int i = 0; i < 3; i++) {

             disruptor.publishEvent(new EventTranslator<MData>() {

                  @Override

                  public void translateTo(MData data, long nextSeq) {

                      data.setValue("MDataProducer - Pushlish...");

                  }

             });

         }

         countDownLatch.countDown();

    }

}

/**

 * 消費者1

 */

class MDataConsumer1 implements EventHandler<MData>,WorkHandler<MData> {

    @Override

    public void onEvent(MData data, long arg1, boolean arg2) throws Exception {

         onEvent(data);

    }

   

    @Override

    public void onEvent(MData data) throws Exception {

         System.out.println("MDataConsumer-1 - setId" + data.getValue());

         data.setId(new Random().nextInt());

//       Thread.sleep(1000);

    }

}

/**

 * 消費者2

 */

class MDataConsumer2 implements EventHandler<MData>,WorkHandler<MData> {

    @Override

    public void onEvent(MData data, long arg1, boolean arg2) throws Exception {

         onEvent(data);

    }

   

    @Override

    public void onEvent(MData data) throws Exception {

         System.out.println("MDataConsumer-2 - setValue" + data.getValue());

         data.setValue("C2");

         Thread.sleep(1000);

    }

}

/**

 * 消費者3

 */

class MDataConsumer3 implements EventHandler<MData> {

    @Override

    public void onEvent(MData data, long nextSeq, boolean endOfBatch) throws Exception {

         System.out.println("MDataConsumer-3" + data.getId() + " - " + data.getValue() + " - " + data);

         data.setValue("C3");

    }

}

/**

 * 消費者4

 */

class MDataConsumer4 implements EventHandler<MData>,WorkHandler<MData> {

    @Override

    public void onEvent(MData data, long arg1, boolean arg2) throws Exception {

         onEvent(data);

    }

    @Override

    public void onEvent(MData data) throws Exception {

         System.out.println("MDataConsumer-4" + data.getId() + " - " + data.getValue() + " - " + data);

         data.setValue("C4");

    }

}

/**

 * 消費者5

 */

class MDataConsumer5 implements EventHandler<MData>,WorkHandler<MData> {

    @Override

    public void onEvent(MData data, long arg1, boolean arg2) throws Exception {

         onEvent(data);

    }

    @Override

    public void onEvent(MData data) throws Exception {

         System.out.println("MDataConsumer-5" + data.getId() + " - " + data.getValue() + " - " + data);

         data.setValue("C5");

    }

}

 

多消費者多生產者玩法

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.Executors;

import java.util.concurrent.atomic.AtomicInteger;

import java.util.function.Consumer;

 

import com.lmax.disruptor.EventFactory;

import com.lmax.disruptor.ExceptionHandler;

import com.lmax.disruptor.RingBuffer;

import com.lmax.disruptor.SequenceBarrier;

import com.lmax.disruptor.WorkHandler;

import com.lmax.disruptor.WorkerPool;

import com.lmax.disruptor.YieldingWaitStrategy;

import com.lmax.disruptor.dsl.ProducerType;

 

/**

 * 多生產者、多消費者

 */

public class D05MultiPWithC {

    public static void main(String[] args) throws InterruptedException {

         //創建RingBuffer

         RingBuffer<Order> ringBuffer = RingBuffer.create(ProducerType.MULTI, new EventFactory<Order>() {

             @Override

             public Order newInstance() {

                  return new Order();

             }

         }, 1024 * 1024, new YieldingWaitStrategy());

        

         SequenceBarrier newBarrier = ringBuffer.newBarrier();

        

         //消費者

         OConsumer [] oConsumers = new OConsumer[3];

         for (int i = 0; i < oConsumers.length; i++) {

             oConsumers[i] = new OConsumer(i + 10);

         }

        

         //消息處理器

         WorkerPool<Order> workerPool = new WorkerPool<>(ringBuffer, newBarrier, new MyEventExceptionHandler(),oConsumers);

        

         //把消費者的位置信息引入注入到生產者,讓生產者可以根據消費者的情況決定生產的速度,避免一個快、一個慢,如果只有一個消費者的情況可以省略

         ringBuffer.addGatingSequences(workerPool.getWorkerSequences());

         workerPool.start(Executors.newFixedThreadPool(5));

        

         CountDownLatch countDownLatch = new CountDownLatch(1);

        

         for (int i = 0; i < 3; i++) {

             OProducer oProducer = new OProducer(ringBuffer);

             new Thread(new Runnable() {

                  @Override

                  public void run() {

                      try {

                          countDownLatch.await();

                      } catch (InterruptedException e) {

                          e.printStackTrace();

                      }

                      for (int j = 0; j < 3; j++) {

                          oProducer.publish(j);

                      }

                  }

             }).start();

         }

         Thread.sleep(3000);

         System.out.println("生產完畢");

         countDownLatch.countDown();

         Thread.sleep(5000);

         System.out.println("總:" + oConsumers[0].getCount().get());

    }

}

class Order {

    private int id;

 

    public int getId() {

         return id;

    }

 

    public void setId(int id) {

         this.id = id;

    }

}

/**

 * 生產者

 */

class OProducer {

   

    private RingBuffer<Order> ringBuffer;

 

    public OProducer(RingBuffer<Order> ringBuffer) {

         super();

         this.ringBuffer = ringBuffer;

    }

   

    public void publish(int id) {

         //槽位置

         long nextSeq = ringBuffer.next();

         try {

             Order order = ringBuffer.get(nextSeq);

             order.setId(id);

         } finally {

             //發佈數據

             ringBuffer.publish(nextSeq);

         }

    }

}

/**

 * 消費者

 */

class OConsumer implements WorkHandler<Order> {

   

    private int consumerId;

   

    private static AtomicInteger count = new AtomicInteger();

   

    public OConsumer(int consumerId) {

         super();

         this.consumerId = consumerId;

    }

 

    @Override

    public void onEvent(Order order) throws Exception {

         System.out.println("消費者:" + this.consumerId + " - 數據:" + order.getId());

         count.incrementAndGet();

    }

 

    public static AtomicInteger getCount() {

         return count;

    }

}

/**

 * 異常處理

 */

class MyEventExceptionHandler implements ExceptionHandler {

 

    @Override

    public void handleEventException(Throwable arg0, long arg1, Object arg2) {

    }

 

    @Override

    public void handleOnShutdownException(Throwable arg0) {

    }

 

    @Override

    public void handleOnStartException(Throwable arg0) {

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章