如果我把一个线程放在一个循环中睡觉,netbeans给我一个警告说循环调用Thread.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!");
}
}
据我所知,join等待其他线程完成,但在这种情况下,不是睡觉和加入做同样的事情?那为什么netbeans会引起注意呢?
答案 0 :(得分:30)
join()和sleep()之间存在差异。 join()将等待超时到期或线程完成。 sleep()只会等待指定的时间,除非被打断。因此,join()返回的速度比指定时间快得多。
Netbeans警告你关于sleep()而不是关于join()的原因正是这种差异。 join()等待一些有意义的事情,而sleep()只是坐在那里什么都不做。如果你不等待什么,那么你为什么要等待呢?这很少有意义,因此警告。
答案 1 :(得分:5)
他们可以用来实现同样的事情并不意味着他们以同样的方式被滥用。人们经常滥用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;
答案 2 :(得分:1)
对于这种情况,我认为连接是比使用锁更好的选择..连接简单而优雅。但是如果你使用锁,你也应该使用notify方法和synchronized块,当然你需要一个锁对象..
加入样本,调用线程代码;
t1.start();
System.out.println("waiting for thread t1");
t1.join();
System.out.println("thread t1 has finished its job");
lock sample:调用线程代码;
Object lock = 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();
}
}
这是线程t1代码;
synchronized(lock) {
try {
System.out.println("doing heavy work");
// .....
lock.notify();
}catch (InterruptedException ex) {
e.printStackTrace();
}
}