java 线程休眠和线程连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4561951/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Thread sleep and thread join
提问by Dhruv Gairola
if i put a thread to sleep in a loop, netbeans gives me a caution saying Invoking Thread.sleep in loop can cause performance problems. However, if i were to replace the sleep with join, no such caution is given. Both versions compile and work fine tho. My code is below (check the last few lines for "Thread.sleep()
vs t.join()
").
如果我让一个线程在循环中休眠,netbeans 会警告我说在循环中调用 Thread.sleep 会导致性能问题。但是,如果我用 join 替换 sleep ,则不会给出这样的警告。两个版本都可以编译并正常工作。我的代码如下(检查“ Thread.sleep()
vs t.join()
”的最后几行)。
public class Test{
//Display a message, preceded by the name of the current thread
static void threadMessage(String message) {
String threadName = Thread.currentThread().getName();
System.out.format("%s: %s%n", threadName, message);
}
private static class MessageLoop implements Runnable {
public void run() {
String importantInfo[] = {
"Mares eat oats",
"Does eat oats",
"Little lambs eat ivy",
"A kid will eat ivy too"
};
try {
for (int i = 0; i < importantInfo.length; i++) {
//Pause for 4 seconds
Thread.sleep(4000);
//Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("I wasn't done!");
}
}
}
public static void main(String args[]) throws InterruptedException {
//Delay, in milliseconds before we interrupt MessageLoop
//thread (default one hour).
long patience = 1000 * 60 * 60;
//If command line argument present, gives patience in seconds.
if (args.length > 0) {
try {
patience = Long.parseLong(args[0]) * 1000;
} catch (NumberFormatException e) {
System.err.println("Argument must be an integer.");
System.exit(1);
}
}
threadMessage("Starting MessageLoop thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for MessageLoop thread to finish");
//loop until MessageLoop thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
//Wait maximum of 1 second for MessageLoop thread to
//finish.
/*******LOOK HERE**********************/
Thread.sleep(1000);//issues caution unlike t.join(1000)
/**************************************/
if (((System.currentTimeMillis() - startTime) > patience) &&
t.isAlive()) {
threadMessage("Tired of waiting!");
t.interrupt();
//Shouldn't be long now -- wait indefinitely
t.join();
}
}
threadMessage("Finally!");
}
}
As i understand it, join waits for the other thread to complete, but in this case, arent both sleep and join doing the same thing? Then why does netbeans throw the caution?
据我了解,join 等待另一个线程完成,但在这种情况下,不是 sleep 和 join 都在做同样的事情吗?那为什么netbeans会抛出这个警告呢?
回答by Sergei Tachenov
There is a difference between join() and sleep(). join() will wait until the timeout expires or the thread finishes. sleep() will just wait for the specified amount of time unless interrupted. So it is perfectly possible for join() to return much faster than the specified time.
join() 和 sleep() 之间是有区别的。join() 将等到超时到期或线程完成。除非被中断,否则 sleep() 只会等待指定的时间。所以 join() 完全有可能比指定的时间更快地返回。
The reason why Netbeans warns you about sleep() and not about join() is precisely that difference. join() waits for something meaningful while sleep() just sits there doing nothing. If you aren't waiting for something, then why would you want to wait at all? It is rarely meaningful, hence the warning.
Netbeans 警告您关于 sleep() 而不是关于 join() 的原因正是这种差异。join() 等待一些有意义的事情,而 sleep() 只是坐在那里什么都不做。如果你不是在等什么,那你为什么要等呢?它很少有意义,因此是警告。
回答by Aaron Digulla
That they can be used to achieve the same thing doesn't mean they are abused in the same way. People often abuse Thread.sleep()
when they should really use a lock or something that blocks:
它们可以被用来实现同样的目标并不意味着它们会以同样的方式被滥用。人们Thread.sleep()
在真正应该使用锁或阻塞的东西时经常滥用:
// Allow others to notify me when there's work to do
synchronized (lock) {
try {
lock.wait(); // Much better than a loop with sleep
} catch(InterruptedException e) {
// someone killed me
return;
}
}
// or use a BlockingQueue or similar
Job job = queue.get();
if (job instanceof ExitJob) return;
回答by Gursel Koca
For this case, I think that join is better alternative than using a lock.. join is simple and elegant. But if you use a lock, you should also use notify method , and synchronized block and of course you need a lock object..
对于这种情况,我认为 join 比使用锁更好。 join 简单而优雅。但是如果你使用锁,你也应该使用通知方法和同步块,当然你需要一个锁对象..
join sample , calling thread code ;
加入示例,调用线程代码;
t1.start();
System.out.println("waiting for thread t1");
t1.join();
System.out.println("thread t1 has finished its job");
lock sample : calling thread code ;
锁定示例:调用线程代码;
Object lock = new Object();
对象锁 = new Object();
synchronized(lock) {
try {
t1.start();
System.out.println("waiting for thread t1");
lock.wait();
System.out.println("thread t1 has finished its job");
}catch (InterruptedException ex) {
e.printStackTrace();
}
}
}
Here is thread t1 code;
这是线程 t1 代码;
synchronized(lock) {
try {
System.out.println("doing heavy work");
// .....
lock.notify();
}catch (InterruptedException ex) {
e.printStackTrace();
}
}