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

Posted

技术标签:

【中文标题】线程;创建一个单独的线程来定期做某事【英文标题】:Threads; Creating a separate thread to periodically do something 【发布时间】:2010-11-03 11:02:42 【问题描述】:

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

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

这是我目前所拥有的:

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
    


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

另外,我对这些要求的实现有什么不好的地方吗?我只创建了一个运行然后睡眠的线程,我错过了什么明显的东西吗?我以前没有使用过线程

【问题讨论】:

在静态块中启动线程? :) 【参考方案1】:

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

【讨论】:

【参考方案2】:

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

您应该调用 start() 而不是 run(),因为您是按顺序而不是同时运行该方法。 您只能调用一次 start(),而不能在每次循环迭代中调用一次。之后,线程处于 TERMINATED 状态,您应该创建一个新线程再次运行它 您不应该在静态块中创建线程,这是一种不好的做法,并且线程可能在您希望它运行之前就已运行。

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

这是一个小例子,它可能会做一些类似于你想要的事情:

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

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

【讨论】:

while 循环后少了一个 "" :)【参考方案3】:

我建议您考虑Timer class - 它提供了定期执行任务的功能。 你也可以看看"Timer & TimerTask versus Thread + sleep in Java"问题讨论——在那里你可以找到一些论据和例子。

【讨论】:

【参考方案4】:

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

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

首先,您在自己的静态构造函数中创建类的实例。静态构造函数的目的是初始化您的类可能具有的任何静态状态,然后您的类的哪些实例可能依赖。通过在静态构造函数创建类的实例,所有这些保证都消失了。

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

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

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

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


【讨论】:

【参考方案5】:

几乎永远不会扩展Thread。如果您发现自己这样做了,请退后一步,看看自己是否真的需要改变 Thread 类的工作方式。

几乎所有在我看到extends Thread 的情况下,最好实现Runnable 接口或使用某种形式的Timer

【讨论】:

以上是关于线程;创建一个单独的线程来定期做某事的主要内容,如果未能解决你的问题,请参考以下文章

Qt线程下定时做某事

创建 3 个线程,每个线程都使用 semapore 进行单独的工作以进行同步。我该怎么做?

为啥不创建单独的线程?

我可以暂停和恢复的线程?

命令不在 J2me 的单独线程中工作

vc如何创建 线程池