BlockableEventLoop.java

net.minecraft.util.thread.BlockableEventLoop

信息

  • 全限定名:net.minecraft.util.thread.BlockableEventLoop
  • 类型:public abstract class
  • 包:net.minecraft.util.thread
  • 源码路径:src/main/java/net/minecraft/util/thread/BlockableEventLoop.java
  • 起始行号:L26
  • 实现:Executor, TaskScheduler, ProfilerMeasured
  • 职责:

    TODO

字段/常量

  • BLOCK_TIME_NANOS

    • 类型: long
    • 修饰符: public static final
    • 源码定位: L27
    • 说明:

      TODO

  • delayedCrash

    • 类型: Supplier<CrashReport>
    • 修饰符: private static volatile
    • 源码定位: L28
    • 说明:

      TODO

  • propagatesCrashes

    • 类型: boolean
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • name

    • 类型: String
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L31
    • 说明:

      TODO

  • pendingRunnables

    • 类型: Queue<R>
    • 修饰符: private final
    • 源码定位: L32
    • 说明:

      TODO

  • blockingCount

    • 类型: int
    • 修饰符: private
    • 源码定位: L33
    • 说明:

      TODO

内部类/嵌套类型

构造器

protected BlockableEventLoop(String name, boolean propagatesCrashes) @ L35

  • 构造器名:BlockableEventLoop
  • 源码定位:L35
  • 修饰符:protected

参数:

  • name: String
  • propagatesCrashes: boolean

说明:

TODO

方法

下面的方法块按源码顺序生成。

protected abstract boolean shouldRun(R task) @ L41

  • 方法名:shouldRun
  • 源码定位:L41
  • 返回类型:boolean
  • 修饰符:protected abstract

参数:

  • task: R

说明:

TODO

public boolean isSameThread() @ L43

  • 方法名:isSameThread
  • 源码定位:L43
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

protected abstract Thread getRunningThread() @ L47

  • 方法名:getRunningThread
  • 源码定位:L47
  • 返回类型:Thread
  • 修饰符:protected abstract

参数:

说明:

TODO

protected boolean scheduleExecutables() @ L49

  • 方法名:scheduleExecutables
  • 源码定位:L49
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

public int getPendingTasksCount() @ L53

  • 方法名:getPendingTasksCount
  • 源码定位:L53
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public String name() @ L57

  • 方法名:name
  • 源码定位:L57
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public <V> CompletableFuture<V> submit(Supplier<V> supplier) @ L62

  • 方法名:submit
  • 源码定位:L62
  • 返回类型: CompletableFuture
  • 修饰符:public

参数:

  • supplier: Supplier

说明:

TODO

private CompletableFuture<Void> submitAsync(Runnable runnable) @ L66

  • 方法名:submitAsync
  • 源码定位:L66
  • 返回类型:CompletableFuture
  • 修饰符:private

参数:

  • runnable: Runnable

说明:

TODO

public CompletableFuture<Void> submit(Runnable runnable) @ L73

  • 方法名:submit
  • 源码定位:L73
  • 返回类型:CompletableFuture
  • 修饰符:public

参数:

  • runnable: Runnable

说明:

TODO

public void executeBlocking(Runnable runnable) @ L83

  • 方法名:executeBlocking
  • 源码定位:L83
  • 返回类型:void
  • 修饰符:public

参数:

  • runnable: Runnable

说明:

TODO

public void schedule(R r) @ L91

  • 方法名:schedule
  • 源码定位:L91
  • 返回类型:void
  • 修饰符:public

参数:

  • r: R

说明:

TODO

public void execute(Runnable command) @ L97

  • 方法名:execute
  • 源码定位:L97
  • 返回类型:void
  • 修饰符:public

参数:

  • command: Runnable

说明:

TODO

public void executeIfPossible(Runnable command) @ L107

  • 方法名:executeIfPossible
  • 源码定位:L107
  • 返回类型:void
  • 修饰符:public

参数:

  • command: Runnable

说明:

TODO

protected void dropAllTasks() @ L111

  • 方法名:dropAllTasks
  • 源码定位:L111
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void runAllTasks() @ L115

  • 方法名:runAllTasks
  • 源码定位:L115
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected boolean shouldRunAllTasks() @ L120

  • 方法名:shouldRunAllTasks
  • 源码定位:L120
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

protected boolean pollTask() @ L124

  • 方法名:pollTask
  • 源码定位:L124
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

public void managedBlock(BooleanSupplier condition) @ L137

  • 方法名:managedBlock
  • 源码定位:L137
  • 返回类型:void
  • 修饰符:public

参数:

  • condition: BooleanSupplier

说明:

TODO

protected void waitForTasks() @ L151

  • 方法名:waitForTasks
  • 源码定位:L151
  • 返回类型:void
  • 修饰符:protected

参数:

说明:

TODO

protected void doRunTask(R task) @ L156

  • 方法名:doRunTask
  • 源码定位:L156
  • 返回类型:void
  • 修饰符:protected

参数:

  • task: R

说明:

TODO

public List<MetricSampler> profiledMetrics() @ L167

  • 方法名:profiledMetrics
  • 源码定位:L167
  • 返回类型:List
  • 修饰符:public

参数:

说明:

TODO

public static boolean isNonRecoverable(Throwable t) @ L172

  • 方法名:isNonRecoverable
  • 源码定位:L172
  • 返回类型:boolean
  • 修饰符:public static

参数:

  • t: Throwable

说明:

TODO

private void throwDelayedException() @ L176

  • 方法名:throwDelayedException
  • 源码定位:L176
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

protected boolean hasDelayedCrash() @ L185

  • 方法名:hasDelayedCrash
  • 源码定位:L185
  • 返回类型:boolean
  • 修饰符:protected

参数:

说明:

TODO

public void delayCrash(CrashReport crashReport) @ L189

  • 方法名:delayCrash
  • 源码定位:L189
  • 返回类型:void
  • 修饰符:public

参数:

  • crashReport: CrashReport

说明:

TODO

public static synchronized void relayDelayCrash(CrashReport crashReport) @ L193

  • 方法名:relayDelayCrash
  • 源码定位:L193
  • 返回类型:void
  • 修饰符:public static synchronized

参数:

  • crashReport: CrashReport

说明:

TODO

代码

public abstract class BlockableEventLoop<R extends Runnable> implements Executor, TaskScheduler<R>, ProfilerMeasured {
    public static final long BLOCK_TIME_NANOS = 100000L;
    private static volatile @Nullable Supplier<CrashReport> delayedCrash;
    private final boolean propagatesCrashes;
    private final String name;
    private static final Logger LOGGER = LogUtils.getLogger();
    private final Queue<R> pendingRunnables = Queues.newConcurrentLinkedQueue();
    private int blockingCount;
 
    protected BlockableEventLoop(String name, boolean propagatesCrashes) {
        this.propagatesCrashes = propagatesCrashes;
        this.name = name;
        MetricsRegistry.INSTANCE.add(this);
    }
 
    protected abstract boolean shouldRun(final R task);
 
    public boolean isSameThread() {
        return Thread.currentThread() == this.getRunningThread();
    }
 
    protected abstract Thread getRunningThread();
 
    protected boolean scheduleExecutables() {
        return !this.isSameThread();
    }
 
    public int getPendingTasksCount() {
        return this.pendingRunnables.size();
    }
 
    @Override
    public String name() {
        return this.name;
    }
 
    public <V> CompletableFuture<V> submit(Supplier<V> supplier) {
        return this.scheduleExecutables() ? CompletableFuture.supplyAsync(supplier, this) : CompletableFuture.completedFuture(supplier.get());
    }
 
    private CompletableFuture<Void> submitAsync(Runnable runnable) {
        return CompletableFuture.supplyAsync(() -> {
            runnable.run();
            return null;
        }, this);
    }
 
    @CheckReturnValue
    public CompletableFuture<Void> submit(Runnable runnable) {
        if (this.scheduleExecutables()) {
            return this.submitAsync(runnable);
        } else {
            runnable.run();
            return CompletableFuture.completedFuture(null);
        }
    }
 
    public void executeBlocking(Runnable runnable) {
        if (!this.isSameThread()) {
            this.submitAsync(runnable).join();
        } else {
            runnable.run();
        }
    }
 
    @Override
    public void schedule(R r) {
        this.pendingRunnables.add(r);
        LockSupport.unpark(this.getRunningThread());
    }
 
    @Override
    public void execute(Runnable command) {
        R task = this.wrapRunnable(command);
        if (this.scheduleExecutables()) {
            this.schedule(task);
        } else {
            this.doRunTask(task);
        }
    }
 
    public void executeIfPossible(Runnable command) {
        this.execute(command);
    }
 
    protected void dropAllTasks() {
        this.pendingRunnables.clear();
    }
 
    protected void runAllTasks() {
        while (this.pollTask()) {
        }
    }
 
    protected boolean shouldRunAllTasks() {
        return this.blockingCount > 0;
    }
 
    protected boolean pollTask() {
        this.throwDelayedException();
        R task = this.pendingRunnables.peek();
        if (task == null) {
            return false;
        } else if (!this.shouldRunAllTasks() && !this.shouldRun(task)) {
            return false;
        } else {
            this.doRunTask(this.pendingRunnables.remove());
            return true;
        }
    }
 
    public void managedBlock(BooleanSupplier condition) {
        this.blockingCount++;
 
        try {
            while (!condition.getAsBoolean()) {
                if (!this.pollTask()) {
                    this.waitForTasks();
                }
            }
        } finally {
            this.blockingCount--;
        }
    }
 
    protected void waitForTasks() {
        Thread.yield();
        LockSupport.parkNanos("waiting for tasks", 100000L);
    }
 
    protected void doRunTask(R task) {
        try (Zone ignored = TracyClient.beginZone("Task", SharedConstants.IS_RUNNING_IN_IDE)) {
            task.run();
        } catch (Exception var7) {
            LOGGER.error(LogUtils.FATAL_MARKER, "Error executing task on {}", this.name(), var7);
            if (isNonRecoverable(var7)) {
                throw var7;
            }
        }
    }
 
    @Override
    public List<MetricSampler> profiledMetrics() {
        return ImmutableList.of(MetricSampler.create(this.name + "-pending-tasks", MetricCategory.EVENT_LOOPS, this::getPendingTasksCount));
    }
 
    public static boolean isNonRecoverable(Throwable t) {
        return t instanceof ReportedException r ? isNonRecoverable(r.getCause()) : t instanceof OutOfMemoryError || t instanceof StackOverflowError;
    }
 
    private void throwDelayedException() {
        if (this.propagatesCrashes) {
            Supplier<CrashReport> delayedCrash = BlockableEventLoop.delayedCrash;
            if (delayedCrash != null) {
                throw new ReportedException(delayedCrash.get());
            }
        }
    }
 
    protected boolean hasDelayedCrash() {
        return delayedCrash != null;
    }
 
    public void delayCrash(CrashReport crashReport) {
        delayedCrash = () -> crashReport;
    }
 
    public static synchronized void relayDelayCrash(CrashReport crashReport) {
        Supplier<CrashReport> delayedCrash = BlockableEventLoop.delayedCrash;
        if (delayedCrash == null) {
            BlockableEventLoop.delayedCrash = () -> crashReport;
        } else {
            delayedCrash.get().getException().addSuppressed(crashReport.getException());
        }
    }
}

引用的其他类