Java 我怎样才能使一个线程睡眠一段时间,然后再开始工作?
我有以下代码:Java 我怎样才能使一个线程睡眠一段时间,然后再开始工作?,java,multithreading,thread-sleep,Java,Multithreading,Thread Sleep,我有以下代码: public void run() { try { logger.info("Looking for new tasks to fetch... "); // definitions .. for(Task t: tasks) { logger.info(" Task " + t.getId() + " is being fetched ");
public void run()
{
try
{
logger.info("Looking for new tasks to fetch... ");
// definitions ..
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
}
Thread.sleep(FREQUENCY);
//t.start();
} catch (Exception e)
{
logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
我试图让线程在特定的时间“频率”内休眠,然后再次工作。当我在eclipse中执行这段代码时,线程只工作一次,然后什么也不发生,进程终止。如果我从语句中删除注释:t.start()
,我会得到“FetcherThreadInterrupted:null”。
谁能告诉我哪里出了问题
注意:我希望线程一直工作,但在周期(比如每5分钟)上取数。尝试在不同的线程上执行任务。您需要将睡眠置于无限循环中(或者在需要睡眠时指定正常运行时间的条件下)。到目前为止,sleep方法是在run方法的末尾调用的,您观察到的行为是正确的。 下面的演示代码将在睡眠一秒钟后在控制台上打印“睡眠”。希望能有帮助
import java.util.concurrent.TimeUnit;
public class Test implements Runnable {
/**
* @param args
*/
public static void main(String[] args) {
Test t = new Test();
Thread thread = new Thread(t);
thread.start();
}
public void run() {
try {
// logger.info("Looking for new tasks to fetch... ");
// definitions ..
// for(Task t: tasks)
// {
// logger.info(" Task " + t.getId() + " is being fetched ");
// // processing ... fetching task info from db using some methods
// }
while (true) { // your condition here
TimeUnit.SECONDS.sleep(1);
System.out.println("Sleep");
}
// t.start();
} catch (Exception e) {
// logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
}
代码中缺少任何类型的循环 看起来这个线程实际上在做你让它做的事情:它运行所有的任务,然后休眠一段时间——然后它没有更多的工作要做,所以退出。有几种方法可以解决这个问题,按复杂性和正确性的升序排列:
while(true){…}
)。这样,在线程完成睡眠后,它将循环回到顶部,并再次处理所有任务boolean running=true;
),并在(运行)时将循环更改为。这样,您就有了一种使线程终止的方法(例如,公开一个将running
设置为false
的方法)。有关这一点的详细解释,请参阅Sun的文章
可运行的工作的一部分。我将采用的实际解决方案是去掉休眠,这样您就有了一个可运行的实现,它处理所有任务,然后终止。然后我将创建一个,并将“普通”可运行的提交给执行者——这样,执行者的工作就是定期运行任务
从工程角度来看,最后一个解决方案是理想的。您有一个只运行一次作业并退出的类—只要您想运行作业,就可以在其他上下文中使用它,并且组合得非常好。您有一个executor服务,其任务是调度任意任务-同样,您可以在将来将不同类型的
Runnable
或Callable
传递给该服务,它也将执行调度位。可能最棒的是,您不必自己编写任何调度内容,但可以使用标准库中的一个类专门为您完成这一切(因此可能已经解决了大多数bug,而不是自行生成的并发代码).您需要某种循环来重复您的工作流程。控制流应如何返回到提取部件 您可以将代码放入一个循环中。(可能是while)
您的案例中发生了什么?它运行任务循环,然后休眠一段时间并退出线程。将线程放入循环中,正如其他人在这里提到的那样 我想补充一点,多次调用Thread.start是非法的,这就是为什么会出现异常 如果要生成多个线程,请为要启动的每个线程创建一个线程对象 见()
将成员调用keepRunning添加到主线程中,并实现一个访问器方法,将其设置为false(从需要阻止线程执行任务的任何位置开始)任务调度在Java中具有一流的支持,不要重新发明它。实际上,有两种实现:
Timer
(老式)和ScheduledExecutorService
(新)。阅读它们并围绕它们设计应用程序。您可以尝试ScheduledExecutorService
()。
而美国则是scheduleAtFixedRate
,它:
创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在给定的时间段内启用;也就是说,执行将在initialDelay之后开始,然后是initialDelay+period,然后是initialDelay+2*period,依此类推
如果取消注释
t.start()
,则会出现编译器错误,无法运行它。谢谢@Andrzej。。我找到了ScheduledExtructorService()的代码示例,它展示了如何使用它而不是无限循环
while(condition) // you can make it while(true) if you want it to run infinitely.
{
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
}
Thread.sleep(FREQUENCY);
}
public void run()
{
while (keepRunning) {
try
{
logger.info("Looking for new tasks to fetch... ");
// definitions ..
for(Task t: tasks)
{
logger.info(" Task " + t.getId() + " is being fetched ");
// processing ... fetching task info from db using some methods
t.start();
}
Thread.sleep(FREQUENCY);
} catch (Exception e) {
keepRunning = false;
logger.info("FetcherThread interrupted: "+e.getMessage());
}
}
}