java newScheduledThreadPool(1) 和 newSingleThreadScheduledExecutor() 的区别

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30028825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:20:10  来源:igfitidea点击:

Difference between newScheduledThreadPool(1) and newSingleThreadScheduledExecutor()

java

提问by user4341206

I am wondering what is the difference between these two methods of Executors class? I have a web application where I'm checking some data every 100 ms so that's why I'm using this scheduler with scheduleWithFixedDelay method. I want to know which method should I use in this case (newScheduledThreadPool or newSingleThreadScheduledExecutor)? I also have one more question - in VisualVM where I monitor my Glassfish server I noticed that I have some threads in PARK state - for example:

我想知道 Executors 类的这两种方法有什么区别?我有一个 Web 应用程序,我每 100 毫秒检查一次数据,这就是我使用带有 scheduleWithFixedDelay 方法的调度程序的原因。我想知道在这种情况下我应该使用哪种方法(newScheduledThreadPool 或 newSingleThreadScheduledExecutor)?我还有一个问题——在 VisualVM 中,我在监控 Glassfish 服务器的地方注意到我有一些线程处于 PARK 状态——例如:

java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <3cb9965d> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Is it possible that these threads are connected with scheduler because I don't have any idea what else would create them? These threads are never destroyed, so I am afraid that this could cause some troubles. Here is a screenshot (new Thread-35 will be created in 15minutes and so on...):

这些线程是否可能与调度程序连接,因为我不知道还有什么会创建它们?这些线程永远不会被破坏,所以我担心这会引起一些麻烦。这是一个屏幕截图(新的 Thread-35 将在 15 分钟内创建,依此类推......):

enter image description here

在此处输入图片说明

回答by Tagir Valeev

As documentationstates:

正如文档所述:

Unlike the otherwise equivalent newScheduledThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.

与其他等效的 newScheduledThreadPool(1) 不同,返回的执行器保证不可重新配置以使用其他线程。

So when using newScheduledThreadPool(1)you will be able to add more threads later.

因此,在使用时,newScheduledThreadPool(1)您可以稍后添加更多线程。

回答by wings

newSingleThreadScheduledExecuto()is wrapped by a delegate, as you can see in Executors.java:

newSingleThreadScheduledExecuto()由委托包装,正如您在Executors.java 中看到的:

public static ScheduledExecutorService newSingleThreadScheduledExecutor() {
    return new DelegatedScheduledExecutorService(new ScheduledThreadPoolExecutor(1));
}

Differences (from javadoc):

差异(来自 javadoc):

if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.

Unlike the otherwise equivalent {@code newScheduledThreadPool(1)} the returned executor is guaranteed not to be reconfigurable to use additional threads.

如果这个单线程在关闭之前由于执行失败而终止,如果需要执行后续任务,一个新线程将取而代之。

与其他等效的 {@code newScheduledThreadPool(1)} 不同,返回的执行器保证不可重新配置以使用其他线程。

reply to your comment:

回复你的评论:

do this also apply for newScheduledThreadPool(1) or not?

这是否也适用于 newScheduledThreadPool(1) ?

no, you need to take care of thread failure yourself.

不,您需要自己处理线程故障。

As for Unsafe.park(), see this.

至于 Unsafe.park(),请看这个

回答by venergiac

As pointed out by wings and tagir the differences is in "how to manage failure".

正如wings和tagir所指出的,区别在于“如何管理失败”。

About Thread your thread is in Wait status; parkis not a status but is a method to put the Thread in wait status; see also

关于线程您的线程处于等待状态;park不是状态而是将线程置于等待状态的方法;也可以看看

How to detect thread being blocked by IO?

如何检测被IO阻塞的线程?

However, let me suggest a different way to implement a scheduled thread on Java EE; you should take a look at EJB's TimerService

但是,让我建议一种在 Java EE 上实现预定线程的不同方法;你应该看看 EJB 的TimerService

@Singleton
public class TimerSessionBean {
    @Resource
    TimerService timerService;   

    public void setTimer(long intervalDuration) {
        Timer timer = timerService.createTimer(intervalDuration, 
                "Created new programmatic timer");
    }

    @Timeout
    public void lookForData(Timer timer) {
        //this.setLastProgrammaticTimeout(new Date());
        ....
    }

    //OR
    @Schedule(minute = "*/1", hour = "*")
    public void runEveryMinute() {
      ...
    }

   }