开发者

Threads; Creating a separate thread to periodically do something

开发者 https://www.devze.com 2023-01-23 12:11 出处:网络
As an addition to my current application, I need to create a separate thread which will periodically do some processing

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 t开发者_JAVA百科here 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


Java offers ScheduledExecutorService to 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.


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.

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.


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.


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().

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 within the 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.

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 Runnable interface. This allows you to decouple the mechanism of the thread, from the behaviour you intend to run.

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();
    }

}


It is almost never right 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 Thread class works.

Almost all occurances where I see extends Thread the job would be better done implementing the Runnable interface or using some form of Timer.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号