Files
KLALB/src/org/kne/concurrent/HighPerformanceExecutor2.java
T

134 lines
3.1 KiB
Java

package org.kne.concurrent;
import java.util.Queue;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import org.jctools.queues.MpscArrayQueue;
import org.kne.cloud.network.klalb.PerformanceStrategy;
public class HighPerformanceExecutor2 implements Executor {
private ThreadElement[] threads;
public HighPerformanceExecutor2(int threadcount) {
//this(threadcount,Executors.defaultThreadFactory());
this(threadcount,Thread.ofVirtual().factory());
}
public HighPerformanceExecutor2(int threadcount,ThreadFactory th) {
threads=new ThreadElement[threadcount];
for (int i = 0; i < threadcount; i++) {
ThreadElement t= new ThreadElement();
th.newThread(t).start();
threads[i]=t;
}
}
private static class ThreadElement implements Runnable{
private MpscArrayQueue<Runnable> queue=new MpscArrayQueue<Runnable>(2048);
private AtomicInteger size=new AtomicInteger();
private volatile ThreadParker parker=new ThreadParker();
public Queue<Runnable> getQueue() {
return queue;
}
public int size() {
return queue.size();
}
public long prev=System.nanoTime();
public boolean putTask(Runnable e) {
boolean b=queue.offer(e);
if(b) {
// size.incrementAndGet();
long curr=System.nanoTime();
if(curr-prev>1000L||queue.size()>=8) {
prev=curr;
parker.unpark();
}
}
return b;
}
@Override
public void run() {
while(true) {
Runnable r=queue.poll();
if(r!=null) {
// size.decrementAndGet();
try {
r.run();
}catch(Throwable e) {
e.printStackTrace();
}
ThreadYieldCheckpoint.yieldCheckpoint(1000000L);
}else {
parker.parkNanos(1000000L);
}
}
}
}
@Override
public void execute(Runnable command) {
if(execute0((x)->{command.run();},1000, PerformanceStrategy.MULTI_FILL)) {
return;
}
System.out.println("loss!");
//backup.execute(command);
}
private long vl=0;
private boolean execute0(Consumer<Boolean> command, int limit, PerformanceStrategy strategy) {
if(strategy.equals(PerformanceStrategy.MULTI_SCATTER)){
long ord=vl++;
ThreadElement te= threads[(int) (ord%threads.length)];
boolean b=te.size()>limit;
return te.putTask( ()->{command.accept(b);});
}else {
for (int i = 0; i < threads.length; i++) {
ThreadElement te = threads[i];
boolean b = te.size() > limit;
if (!b) {
if (te.putTask(() -> {
command.accept(false);
})) {
return true;
}
}
}
for (int i = 0; i < threads.length; i++) {
ThreadElement te = threads[i];
if (te.putTask(() -> {
command.accept(true);
})) {
return true;
}
}
return false;
}
}
public void executeWithCongestionReport(Consumer<Boolean> command) {
if(execute0(command,1000, PerformanceStrategy.MULTI_FILL)) {
return;
}
System.out.println("loss!");
}
public void executeWithCongestionReport(Consumer<Boolean> command, int limit, PerformanceStrategy strategy) {
if(execute0(command,limit,strategy)) {
return;
}
System.out.println("loss!");
}
}