4

给定以下课程:

public class Poller implements Runnable {
    public static final int CORE_POOL_SIZE = 4;

    public boolean running;
    public ScheduledExecutorService ses;

    public void startPolling() {
        this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE);
        this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS);
    }

    public void run() {
        running = true;
        // ... Do something ...
        running = false;
    }
}

核心线程池大小为 4 ,ScheduledExecutorService但会创建多个轮询线程吗?既然this被传递到scheduleAtFixedRate,这是否意味着只会有一个线程 - 或者在幕后发生更复杂的事情?

还有 2 个奖励问题:-

  1. 应该runningstatic
  2. CORE_POOL_SIZE多余的吗?
4

3 回答 3

4

ScheduledExecutorService 的核心线程池大小为 4,但是否会创建多个轮询线程?

这取决于 - 如果您运行程序足够长的时间,它可能会创建 4 个线程。如果您只运行一次或两次计划任务后退出,您可能只会看到 2 或 3 个线程。

为什么这有关系?

监视线程创建的一种方法是提供您自己的ThreadFactory

this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE, new ThreadFactory() {

            @Override
            public Thread newThread(Runnable r) {
                System.out.println("Creating thread");
                return new Thread(r);
            }
        }); 

跑步应该是静态的吗?

这取决于您要实现的目标...由于您在示例中并没有真正使用它,因此很难说。例如,如果您有多个 Poller 实例并且您不希望它们同时运行,您可能需要将其设为静态。

无论是静态的还是非静态的,如果你把它作为一个标志使用,你应该让它变得易变以确保可见性。

CORE_POOL_SIZE 是多余的吗?

不明白你的意思。它是一个强制参数,因此您需要提供一个值。如果您确定不会同时运行两个执行,那么您只能有一个线程。这也将阻止并发执行(因此,如果一个计划任务需要启动但另一个已在运行,则新任务将被延迟)。

于 2013-03-15T10:20:29.977 回答
3

scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)

此方法调度要定期执行的任务。该任务在 initialDelay 之后第一次执行,然后每次周期到期时重复执行。

如果给定任务的任何执行引发异常,则不再执行该任务。如果没有抛出异常,任务将继续执行,直到 ScheduledExecutorService 关闭。

如果一个任务的执行时间比其计划执行之间的时间长,则下一次执行将在当前执行完成后开始。计划任务一次不会被多个线程执行。

于 2013-03-16T04:27:00.827 回答
1

你为什么把你的执行者服务放在Runnable课堂上?您应该将您的ScheduledExecutorService作为 Singleton 分开,而不是作为可运行类的变量。

提醒这ScheduledExecutorService是一个线程容器,所以当你编码时

this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE);

当您放置此代码时,它将同时基于大小的值创建很多线程

this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS);

ScheduledExecutorService随机选择一个空闲的线程每 1 秒运行一次此类,直到它完成。如果您sleep输入的运行方法长于传递给预定线程的周期时间值,则在第一个线程完成之前,它不会创建另一个线程。因此,如果您希望多个线程同时运行它Poller,则创建多个Poller实例并将其传递给ScheduledExecutorService

CORE_POOL_SIZE它对我来说不是多余的,最好是从配置文件中获取的常量。

跑步应该是静态的吗?这取决于你需要什么。如果您打算创建多个实例,Poller那么您不应该

于 2013-03-15T11:06:59.643 回答