2010-11-03 188 views
5

作为补充,以我目前的应用程序,我需要创建一个单独的线程将定期做一些处理线程;创建一个单独的线程来定期地做一些事情

我已经创建一个新的类来做到这一切,这个类将在我的应用程序启动时加载。

这是我到目前为止有:

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

在静态块中启动线程? :) – willcodejavaforfood 2010-11-03 11:04:32

回答

9

你有一些概念上的错误回报在你的代码...比如:

  • 您应调用start()和不能运行(),因为你同时运行方法的顺序,而不是。
  • 您可以在每次循环迭代中只调用一次start(),而不是一次。在此之后,线程状态终止,您应该创建一个新的线程来运行它再次
  • 你不应该建立在静态块中的线程,这是一个不好的做法,也许线程运行,你想让它之前跑步。

您应该阅读一些关于线程的示例,在开始处稍微难以忽略,并且您可能非常容易产生不期望的效果。

这里是一个小例子,可以做一些类似的东西,你想:

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

如果你想无人能创建一个新的线程,你可以创建一个单例,所以你一定会认为没有人创建更多线程。

+0

有一个“}” while循环后失踪:) – Keshav 2011-07-08 08:51:37

+0

我固定的花括号,谢谢。 – greuze 2011-08-10 09:12:41

3

首先回答你的具体问题,你已经实现了你的目标。你已经声明你的构造函数是私有的,没有外部类可以像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(); 
    } 

} 
2

这是几乎从来没有权利延伸Thread。如果你发现自己在做这件事,请退后一步,看看自己是否真的需要改变Thread课程的工作方式。

几乎所有 occurances在那里我看到extends Thread工作会做得更好实现Runnable界面或使用某种形式的Timer

12

Java提供ScheduledExecutorService来延迟调度和运行周期性任务或任务。它应该提供您需要的所有功能。计时器是另一个类,提供相似的功能,但我会建议在定时器ScheduledExecutorService的配置和更好的错误管理的灵活性。