作为我当前应用程序的补充,我需要创建一个单独的线程,它会定期进行一些处理
我已经创建了一个新类来完成所有这些操作,这个类将在我的应用程序启动时加载。
这是我到目前为止所做的:
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
}
}
我想将构造函数设为私有,以防止其他人意外地尝试实例化此类。我怎样才能做到这一点?
另外,我对这些要求的实施有什么不好吗?我只创建一个会运行然后睡觉的线程,我是否错过了任何明显的错误?
之前我没有使用过线程答案 0 :(得分:12)
Java提供ScheduledExecutorService来安排和运行具有延迟的周期性任务或任务。它应该提供您需要的所有功能。 Timer是另一个提供类似功能的类,但我建议使用ScheduledExecutorService over Timer,因为它具有灵活的配置和更好的错误管理。
答案 1 :(得分:10)
您的代码中有一些概念错误...例如:
你应该阅读一些关于线程的例子,一开始就有点难以理解,你很容易产生不良影响。
这是一个小例子,可以做一些你想要的事情:
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();
}
}
如果你想要没有人可以创建一个新的线程,你可以创建一个单例,这样你就可以确保没有人创建更多的线程。
答案 2 :(得分:4)
我建议您考虑Timer class - 它提供定期任务执行的功能。 您也可以查看"Timer & TimerTask versus Thread + sleep in Java"问题讨论 - 在那里您可以找到一些参数和示例。
答案 3 :(得分: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();
}
}
答案 4 :(得分:2)
几乎从不对Thread
进行扩展。如果你发现自己这样做了,请退一步看看自己是否真的需要改变Thread
类的工作方式。
几乎所有出现,我看到extends Thread
这项工作最好在实施Runnable
界面或使用某种形式的Timer
时完成。