java 线程;创建一个单独的线程来定期做某事

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4086365/
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-10-30 04:43:00  来源:igfitidea点击:

Threads; Creating a separate thread to periodically do something

javamultithreadingthread-safety

提问by Jimmy

As an addition to my current application, I need to create a separate thread which will periodically do some processing

作为我当前应用程序的补充,我需要创建一个单独的线程,它会定期进行一些处理

I've create a new class to do all this, and this class will be loaded on startup of my application.

我创建了一个新类来完成所有这些工作,这个类将在我的应用程序启动时加载。

This is what I have so far :

这是我到目前为止:

public class PeriodicChecker extends Thread
{
    static
    {
        Thread t = new Thread(new PeriodicChecker());
        while(true)
        {
            t.run();
            try
            {
                Thread.sleep(5000l);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
    }

    /**
     * Private constructor to prevent instantiation
     */
    private PeriodicChecker()
    {

    }

    @Override
    public void run()
    {
        System.out.println("Thread is doing something");
        // Actual business logic here, that is repeated
    }

}

I want to make constructor private to prevent other people from attempting to instantiate this class accidentally. How can I achieve this?

我想将构造函数设为私有以防止其他人意外地尝试实例化此类。我怎样才能做到这一点?

Also, is there anything bad about my implementation of such requirements? I'm only creating one thread which will run then sleep, have I missed anything obvious? I haven't worked with threads before

另外,我对这些要求的实现有什么不好的地方吗?我只创建了一个线程,该线程将运行然后睡眠,我是否遗漏了任何明显的内容?我以前没有使用过线程

回答by sjlee

Java offers ScheduledExecutorServiceto schedule and run periodic tasks or tasks with delay. It should provide all the features you need. Timer is another class that offers similar functionalities, but I would recommend the ScheduledExecutorService over Timer for its flexibility of configuration and better error management.

Java 提供ScheduledExecutorService来调度和运行周期性任务或延迟任务。它应该提供您需要的所有功能。Timer 是另一个提供类似功能的类,但我更推荐 ScheduledExecutorService 而不是 Timer,因为它具有配置的灵活性和更好的错误管理。

回答by greuze

You have some conceptual erros in your code... for example:

您的代码中有一些概念性错误……例如:

  • You should call start() and not run(), because you are running the method sequentially and not simultaneously.
  • You can call start() only once, not once in each loop iteration. After that, the thread is in state TERMINATED, you should create a new thread to run it again
  • You should not create the thread in the static block, it is a bad practice, and maybe the Thread is running before you want it to run.
  • 您应该调用 start() 而不是 run(),因为您是按顺序运行该方法而不是同时运行。
  • 您只能调用 start() 一次,而不能在每次循环迭代中调用一次。之后,线程处于 TERMINATED 状态,您应该创建一个新线程再次运行它
  • 您不应该在静态块中创建线程,这是一种不好的做法,并且线程可能在您希望它运行之前就已运行。

You should read some examples about thread, it is a little difficult to unserstand at the beginning, and you can have undesired effects very easily.

您应该阅读一些有关线程的示例,一开始有点难以理解,并且很容易产生不良影响。

Here is a little example, that may do something similar to that you want:

这是一个小示例,它可能会执行与您想要的类似的操作:

public class PeriodicChecker extends Thread
{
    @Override
    public void run()
    {
        while(true) {
           System.out.println("Thread is doing something");
           Thread.sleep(5000);
        }
    }

}

public OtherClass {
   public static void main(String args[]) {
      Thread t = new PeriodicChecker();
      t.start();
   }
}

If you want that none can create a new Thread, you could create a singleton, so you will be sure that none is creating more threads.

如果您希望没有人可以创建新线程,则可以创建一个单例,这样您就可以确定没有人会创建更多线程。

回答by Kel

I'd recommend you to consider Timer class- it provides functionality for periodic tasks execution. Also you may take a look at "Timer & TimerTask versus Thread + sleep in Java"question discussion - there you can find some arguments and examples.

我建议您考虑Timer 类- 它提供周期性任务执行的功能。您也可以查看“Java 中的 Timer & TimerTask 与线程 + 睡眠”问题讨论 - 在那里您可以找到一些参数和示例。

回答by Jared Russell

First of all to answer your specific question, you have already achieved your objective. You have declared your constructor to be private meaning no external class can call it like new PeriodicChecker().

首先回答你的具体问题,你的目的已经达到了。您已将构造函数声明为私有,这意味着没有外部类可以像new PeriodicChecker().

Looking at your code however, there are a number of other problems:

但是,查看您的代码,还有许多其他问题:

Firstly, you are creating an instance of your class within its own static constructor. The purpose of a static constructor is to initialise any static state that your class may have, which instances of your class may then depend on. By creating an instance of the class withinthe static constructor, all of these guarantees go out the window.

首先,您在自己的静态构造函数中创建类的实例。静态构造函数的目的是初始化您的类可能具有的任何静态状态,然后您的类的实例可能依赖于这些状态。通过创建类的实例的静态构造函数,所有这些担保走出去的窗口。

Secondly, I don't think your thread is going to behave in the way you expect it to behave, primarily because you don't actually start another thread :). If you intend to start a new thread, you need to call the start()method on that thread object. Calling run()as you do does not actually create a new thread, but simply runs the run()method in the current thread.

其次,我认为您的线程不会按照您期望的方式运行,主要是因为您实际上并没有启动另一个线程:)。如果您打算启动一个新线程,则需要调用该start()线程对象上的方法。run()像您一样调用实际上并不会创建新线程,而只是run()在当前线程中运行该方法。

Nowadays when you want to create a new thread to do something, the reccomended way of achieving this is to not extend Thread, but instead implement the Runnableinterface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.

现在当你想创建一个新线程来做某事时,推荐的实现方式是不扩展Thread,而是实现Runnable接口。这允许您将线程的机制与您打算运行的行为分离。

Based on your requirements, I would suggest doing away with a top-level class like this, and instead create either a private inner class within your application start-up code, or even go for an anonymous inner class:

根据您的要求,我建议取消像这样的顶级类,而是在您的应用程序启动代码中创建一个私有内部类,或者甚至去创建一个匿名内部类:

public class Main {

    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("Thread is doing something");
                    Thread.sleep(5000);
                }
            }
        }).start();
    }

}

回答by Qwerky

It is almost neverright to extend Thread. If you ever find yourself doing this, step back, take a look and ask yourself if you really need to change the way the Threadclass works.

这是几乎从来没有正确的扩展Thread。如果你发现自己这样做了,退后一步,看看并问问自己是否真的需要改变Thread课堂的运作方式。

Almost alloccurances where I see extends Threadthe job would be better done implementing the Runnableinterface or using some form of Timer.

几乎所有我看到extends Thread的工作都会更好地实现Runnable接口或使用某种形式的Timer.