线程;创建一个单独的线程来定期做某事
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
。
【讨论】:
以上是关于线程;创建一个单独的线程来定期做某事的主要内容,如果未能解决你的问题,请参考以下文章