Java Can';这';是否传递到ScheduleExecutorService.scheduleWithFixedDelay()中?
我正在考虑将Java Can';这';是否传递到ScheduleExecutorService.scheduleWithFixedDelay()中?,java,multithreading,concurrency,scheduled-tasks,polling,Java,Multithreading,Concurrency,Scheduled Tasks,Polling,我正在考虑将java.util.concurrent包用于一个简单的轮询类。我对可用于此操作的类、接口和方法的范围有点困惑,因此希望您提供一些指导。到目前为止,我的想法如下: 要做的第一个决定是如何实例化用于管理计划的类。有几种可能的选择,例如: ScheduledThreadPoolExecutor scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize) ……或者 ScheduledExe
java.util.concurrent
包用于一个简单的轮询类。我对可用于此操作的类、接口和方法的范围有点困惑,因此希望您提供一些指导。到目前为止,我的想法如下:
要做的第一个决定是如何实例化用于管理计划的类。有几种可能的选择,例如:
ScheduledThreadPoolExecutor scheduledThreadPoolExecutor =
new ScheduledThreadPoolExecutor(corePoolSize)
……或者
ScheduledExecutorService scheduledExecutorService =
Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(corePoolSize);
……或者
ScheduledExecutorService scheduledExecutorService =
Executors.newSingleThreadScheduledExecutor();
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(corePoolSize);
我倾向于最后一个,但想知道一个合理的corePoolSize应该是什么-也许是为了保持简单
编辑:最后,我发现使用top方法(即直接实例化)最有好处。用于获取活动线程的数量。这使我能够实现一个pause()
方法,该方法将等待暂停实际生效-请参阅
下一个决定是打电话还是打电话。我倾向于scheduleWithFixedDelay()
,因为轮询的规律性并不那么重要,我不喜欢瓶颈过后快速连续进行多次轮询的想法
但问题是:使用一个既开始轮询又表示线程的类是否合适/可取?例如:
public class Poller extends Thread {
@Override
public void run() {
...
}
public void startPolling() {
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.scheduleWithFixedDelay(this, 0, 5000, TimeUnit.MILLISECONDS);
}
}
这里我不确定的主要部分是第一个
scheduleWithFixedDelay()
参数:是否会为每次执行实例化此类的新实例?否则它肯定不起作用,因为run()不能在同一个线程实例上被调用两次?正如其他人所评论的,您只需要将Thread更改为Runnable即可。您可能需要添加一些安全防护装置,以便不会运行多个任务
public class Poller implements Runnable {
final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
Future future = null;
@Override
public void run() {
...
}
public void startPolling() {
if (future != null && !future.isDone()) {
future.cancel(true); // stop before restarting
// or
return; // already running
}
future = exec.scheduleWithFixedDelay(this, 0, 5000, TimeUnit.MILLISECONDS);
}
}
顺便说一句:如果您有Java 5.0,run()
方法没有@覆盖
。对于Java6+,您应该具有@Override
是否会为每次执行实例化此类的新实例
使用new
操作符时,将创建一个新实例
否则它肯定不会工作run()肯定不能在同一线程实例上调用两次
它可以工作,因为在代码中使用线程是令人困惑的,因为您创建的线程没有被使用。它只需要是
可运行的
单线程方法可以使用轮询器
实现,如下所示:
public class Poller implements Runnable {
public void run() {
while ( mayContinue ) {
poll();
Thread.sleep(5000);
}
}
}
轮询器
不应扩展线程
,而应只实现可运行
!-不会创建传递的Runnable
的新实例。run()
方法只是被多次调用。我们不会将Thread
提交给ExecutorService
。Executors
的全部目的是提供一个线程池来同时执行任务。如您的示例所示,如果您只希望一个线程定期执行一些轮询,您通常会自己启动/管理该线程,如thread myThread=new thread(myPoller);myThread.start()代码>。这些都是很好的注释,而且已经更有意义了。我习惯于扩展线程而不是实现Runnable,因为这通常是推荐的方法。因此,如果我改用Runnable,那么似乎每次执行都会重用同一个实例?希望Oracle文档中提到这一点!想象一下,如果不是这样的话。ExecutorService
如何为下一次执行创建对象的新实例这根本不可能。再次谢谢你,汉诺。这看起来简单多了——曾经考虑过做类似的事情,但后来采用了StackOverflow,并转向了java.concurrency
——但考虑到它的规模相当小,这可能是过虑了。唯一的问题是,我正在与一个现有产品集成,对它如何使用线程知之甚少——因此,也许java.concurrency可以防止潜在的问题和未来的证明。。。我现在有点不知所措了mayContinue
必须是易失性的,Thread.sleep抛出一个必须捕获的InterruptedException。那么您建议Peter使用哪种方法?我猜ScheduledExecutorService必须存在,因为它可以防止所有常见的线程问题……如果可以的话,ExecutorService
s可以有效地并发执行多个(通常较短)任务。例如,一个执行器可以使用一个线程来处理一个又一个任务的加载,而无需创建除第一个线程之外的另一个线程。Executor
还可以使用多个线程池来处理其任务,再次重复使用线程,而不是一次又一次地创建新线程。ScheduledExecutorService
基本上与附加选项相同,它可以自动延迟或重复给定的任务,而不是一次性处理它们。谢谢。这看起来像是很好的代码。希望有办法分享答案,因为你和汉诺都提供了宝贵的意见。如果是这样,我会把它交给代表性最少的人。;)