首页 > 解决方案 > 发送到 scheduleAtFixedRate 时线程名称不匹配

问题描述

我创建了一个可运行的类并创建了一个线程,但具有唯一的名称,但是当我发送这个线程时,虽然executor.scheduleAtFixedRate它创建了自己的线程,但我不明白为什么会这样?

我试图在这里阅读,但我仍然不明白: https ://www.codejava.net/java-core/concurrency/java-concurrency-scheduling-tasks-to-execute-after-a-given-delay-或定期

public class Main {

    public static void main(String[] args) throws ClassNotFoundException {
        ScheduledExecutorService executor =
                Executors.newSingleThreadScheduledExecutor();
        Runnable runnable = new AutoUpdater();
        Thread thread = new Thread(runnable, "MyThread");
        executor.scheduleAtFixedRate(thread, 0, 24, TimeUnit.HOURS);
    }
}

public class AutoUpdater implements Runnable {
    public void run() {
        String threadName = Thread.currentThread().getName();
        System.out.println(threadName + " is running...");
        System.out.println("Thread ended.\n");
    }
}

它应该打印名称 MyThread 但输出是:

pool-1-thread-1

它应该是这样的:

pool-1-MyThread-1

标签: javathreadpool

解决方案


问题是Executors.newSingleThreadScheduledExecutor()创建了一个在内部拥有自己线程的池。

当你看ScheduledExecutorService::scheduleAtFixedRate它时,它Runnable作为第一个论点。这Runnable将由池中的某个线程运行。请注意,Thread实现Runnable并且您将Thread实例传递给scheduleAtFixedRate方法,因此该线程的 run 方法将被其他线程调用,但您传递的线程将不会被启动。一般来说,为了避免任何误解,你应该Runnable在这里传递简单的,这将代表需要完成的工作。

如果要更改此池中的线程名称,则必须提供 customThreadFactory将由池用于创建新线程:

ThreadFactory threadFactory = runnable -> new Thread(runnable, "MyThreadName");

ScheduledExecutorService executor =
            Executors.newSingleThreadScheduledExecutor(threadFactory);

编辑

对于 < 8 的 Java 版本,我们可以简单地创建新的类实现ThreadFactory接口:

class MyThreadFactory implements ThreadFactory {
    @Override
    public Thread newThread(Runnable runnable) {
        return new Thread(runnable, "MyThreadName");
    }
}

然后通过它:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new MyThreadFactory());

推荐阅读