115 lines
3.3 KiB
Java
115 lines
3.3 KiB
Java
package org.kne.concurrent;
|
|
|
|
import java.util.concurrent.Executor;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
import java.util.concurrent.ThreadFactory;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
import com.lmax.disruptor.BlockingWaitStrategy;
|
|
import com.lmax.disruptor.EventFactory;
|
|
import com.lmax.disruptor.EventHandler;
|
|
import com.lmax.disruptor.EventTranslator;
|
|
import com.lmax.disruptor.LiteBlockingWaitStrategy;
|
|
import com.lmax.disruptor.RingBuffer;
|
|
import com.lmax.disruptor.Sequence;
|
|
import com.lmax.disruptor.SequenceBarrier;
|
|
import com.lmax.disruptor.SleepingWaitStrategy;
|
|
import com.lmax.disruptor.YieldingWaitStrategy;
|
|
import com.lmax.disruptor.dsl.Disruptor;
|
|
import com.lmax.disruptor.dsl.ProducerType;
|
|
|
|
|
|
public class DisruptorExecutor implements Executor{
|
|
|
|
public static final DisruptorExecutor defaultExecutor=new DisruptorExecutor();
|
|
private RunnableHandler[]rh;
|
|
|
|
public DisruptorExecutor() {
|
|
this(Runtime.getRuntime().availableProcessors(),1024);
|
|
}
|
|
public DisruptorExecutor(int threadcount,int bufferSize) {
|
|
this(threadcount,bufferSize,Executors.defaultThreadFactory());
|
|
//this(threadcount,bufferSize,Thread.ofVirtual().factory());
|
|
}
|
|
public DisruptorExecutor(int threadcount,int bufferSize,ThreadFactory th) {
|
|
|
|
|
|
|
|
rh=new RunnableHandler[threadcount];
|
|
|
|
for (int i = 0; i < rh.length; i++) {
|
|
rh[i]=new RunnableHandler(bufferSize,th);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private class RunnableHandler implements EventHandler<AtomicReference<Runnable>>{
|
|
|
|
private Disruptor<AtomicReference<Runnable>>ring;
|
|
public RunnableHandler(int bufferSize,ThreadFactory tf)
|
|
{ring=new Disruptor<AtomicReference<Runnable>>(new EventFactory<AtomicReference<Runnable>>() {
|
|
|
|
@Override
|
|
public AtomicReference<Runnable> newInstance() {
|
|
return new AtomicReference<Runnable>();
|
|
}
|
|
}, bufferSize,tf,ProducerType.MULTI, new SleepingWaitStrategy());
|
|
ring.handleEventsWith(this);
|
|
ring.start();
|
|
}
|
|
|
|
@Override
|
|
public void onEvent(AtomicReference<Runnable> arg0, long sequence, boolean onEndOfBatch) throws Exception {
|
|
//System.out.println(sequence);
|
|
Runnable r =arg0.get();
|
|
if(r!=null)
|
|
try {
|
|
r.run();
|
|
}catch(Throwable th) {
|
|
th.printStackTrace();
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
/*
|
|
* public final class MyHandler implements EventHandler<ValueEvent>
|
|
{
|
|
|
|
public void onEvent(final ValueEvent entry, final long sequence, final boolean onEndOfBatch)
|
|
{
|
|
if ((sequence % numberOfConsumers) == ordinal)
|
|
{
|
|
// Process the event
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
private AtomicLong al=new AtomicLong();
|
|
@Override
|
|
public void execute(Runnable command) {
|
|
int v=(int) (al.getAndIncrement()%rh.length);
|
|
rh[v].ring.publishEvent(new EventTranslator<AtomicReference<Runnable>>() {
|
|
|
|
@Override
|
|
public void translateTo(AtomicReference<Runnable> arg0, long arg1) {
|
|
arg0.set(command);
|
|
//arg0.compareAndSet(null, command);
|
|
}
|
|
});
|
|
}
|
|
public static void main(String[] args) throws InterruptedException {
|
|
DisruptorExecutor dre=new DisruptorExecutor();
|
|
for (int i = 0; i < 20; i++) {
|
|
dre.execute(()->{
|
|
System.out.println("run");
|
|
});
|
|
System.out.println("exc");
|
|
}
|
|
Thread.sleep(1000);
|
|
}
|
|
}
|