ThreadingDetector.java

net.minecraft.util.ThreadingDetector

信息

  • 全限定名:net.minecraft.util.ThreadingDetector
  • 类型:public class
  • 包:net.minecraft.util
  • 源码路径:src/main/java/net/minecraft/util/ThreadingDetector.java
  • 起始行号:L17
  • 职责:

    TODO

字段/常量

  • LOGGER

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

      TODO

  • name

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

      TODO

  • lock

    • 类型: Semaphore
    • 修饰符: private final
    • 源码定位: L20
    • 说明:

      TODO

  • stackTraceLock

    • 类型: Lock
    • 修饰符: private final
    • 源码定位: L21
    • 说明:

      TODO

  • threadThatFailedToAcquire

    • 类型: Thread
    • 修饰符: private volatile
    • 源码定位: L22
    • 说明:

      TODO

  • fullException

    • 类型: ReportedException
    • 修饰符: private volatile
    • 源码定位: L23
    • 说明:

      TODO

内部类/嵌套类型

构造器

public ThreadingDetector(String name) @ L25

  • 构造器名:ThreadingDetector
  • 源码定位:L25
  • 修饰符:public

参数:

  • name: String

说明:

TODO

方法

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

public void checkAndLock() @ L29

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

参数:

说明:

TODO

public void checkAndUnlock() @ L54

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

参数:

说明:

TODO

public static ReportedException makeThreadingException(String name, Thread threadThatFailedToAcquire) @ L71

  • 方法名:makeThreadingException
  • 源码定位:L71
  • 返回类型:ReportedException
  • 修饰符:public static

参数:

  • name: String
  • threadThatFailedToAcquire: Thread

说明:

TODO

private static String stackTrace(Thread thread) @ L84

  • 方法名:stackTrace
  • 源码定位:L84
  • 返回类型:String
  • 修饰符:private static

参数:

  • thread: Thread

说明:

TODO

代码

public class ThreadingDetector {
    private static final Logger LOGGER = LogUtils.getLogger();
    private final String name;
    private final Semaphore lock = new Semaphore(1);
    private final Lock stackTraceLock = new ReentrantLock();
    private volatile @Nullable Thread threadThatFailedToAcquire;
    private volatile @Nullable ReportedException fullException;
 
    public ThreadingDetector(String name) {
        this.name = name;
    }
 
    public void checkAndLock() {
        boolean released = false;
 
        try {
            this.stackTraceLock.lock();
            if (!this.lock.tryAcquire()) {
                this.threadThatFailedToAcquire = Thread.currentThread();
                released = true;
                this.stackTraceLock.unlock();
 
                try {
                    this.lock.acquire();
                } catch (InterruptedException var6) {
                    Thread.currentThread().interrupt();
                }
 
                throw this.fullException;
            }
        } finally {
            if (!released) {
                this.stackTraceLock.unlock();
            }
        }
    }
 
    public void checkAndUnlock() {
        try {
            this.stackTraceLock.lock();
            Thread threadThatFailedToAcquire = this.threadThatFailedToAcquire;
            if (threadThatFailedToAcquire != null) {
                ReportedException fullException = makeThreadingException(this.name, threadThatFailedToAcquire);
                this.fullException = fullException;
                this.lock.release();
                throw fullException;
            }
 
            this.lock.release();
        } finally {
            this.stackTraceLock.unlock();
        }
    }
 
    public static ReportedException makeThreadingException(String name, @Nullable Thread threadThatFailedToAcquire) {
        String threads = Stream.of(Thread.currentThread(), threadThatFailedToAcquire)
            .filter(Objects::nonNull)
            .map(ThreadingDetector::stackTrace)
            .collect(Collectors.joining("\n"));
        String error = "Accessing " + name + " from multiple threads";
        CrashReport report = new CrashReport(error, new IllegalStateException(error));
        CrashReportCategory category = report.addCategory("Thread dumps");
        category.setDetail("Thread dumps", threads);
        LOGGER.error("Thread dumps: \n{}", threads);
        return new ReportedException(report);
    }
 
    private static String stackTrace(Thread thread) {
        return thread.getName() + ": \n\tat " + Arrays.stream(thread.getStackTrace()).map(Object::toString).collect(Collectors.joining("\n\tat "));
    }
}

引用的其他类

  • CrashReport

    • 引用位置: 构造调用
    • 关联成员: CrashReport()
  • ReportedException

    • 引用位置: 字段/构造调用/返回值
    • 关联成员: ReportedException()