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架構: