鉴于以下课程:
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;
}
}
ScheduledExecutorService
的核心线程池大小为4,但是会创建多个轮询器线程吗?由于this
被传递到scheduleAtFixedRate
,这意味着只会有一个线程 - 或者在幕后发生更复杂的事情吗?
还有2个红利问题: -
running
应该static
吗?CORE_POOL_SIZE
是多余的吗?答案 0 :(得分: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是多余的吗?
不确定你的意思。这是一个必需参数,因此您需要提供一个值。如果你确定不会同时运行两个执行,那么你只能有一个线程。这也将阻止并发执行(因此,如果一个计划任务需要启动但另一个已经运行,则新计划任务将被延迟)。
答案 1 :(得分:3)
scheduleAtFixedRate(Runnable,long initialDelay,long period,TimeUnit timeunit)
此方法安排定期执行的任务。该任务在initialDelay之后第一次执行,然后在每次期限到期时重复执行。
如果给定任务的任何执行引发异常,则不再执行该任务。如果没有抛出异常,则该任务将继续执行,直到ScheduledExecutorService关闭为止。
如果任务执行的时间比其计划执行之间的时间长,则下一次执行将在当前执行完成后开始。计划任务一次不会由多个线程执行。
答案 2 :(得分:1)
为什么要将执行者服务放在Runnable
课程中?
您应该将ScheduledExecutorService
分离为Singleton而不是runnable类的变量。
提醒这个ScheduledExecutorService
是一个线程容器,所以当你编写这个
this.ses = Executors.newScheduledThreadPool(CORE_POOL_SIZE);
当你输入这段代码时,它会根据大小的值创建很多线程
this.ses.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS);
ScheduledExecutorService
将随机选择一个空闲的线程,每隔1秒运行一次该类,直到完成为止。如果将sleep
放在run time方法中,该方法的长度超过了period time的值,则传递给预定的线程,它将不会创建另一个线程,直到第一个线程完成。因此,如果您希望多个线程同时运行此Poller
,请创建多个Poller
实例并将其传递给ScheduledExecutorService
CORE_POOL_SIZE
对我来说这不是多余的,从配置文件中获取值是一个常量。
运行应该是静态的吗?
这取决于你需要什么。如果你打算创建Poller
的多个实例,那么你不应该