2010-12-30 30 views
8

nếu tôi đặt một chủ đề để ngủ trong một vòng lặp, netbeans cho tôi một thận trọng nói Invoking Thread.sleep trong vòng lặp có thể gây ra vấn đề hiệu suất. Tuy nhiên, nếu tôi đã thay thế giấc ngủ bằng cách tham gia, không có cảnh báo như vậy được đưa ra. Cả hai phiên bản biên dịch và làm việc tốt tho. Mã của tôi ở bên dưới (hãy kiểm tra một vài dòng cuối cùng cho "Thread.sleep() vs t.join()").Chủ đề ngủ và thread tham gia

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!"); 
    } 
} 

Khi tôi hiểu nó, hãy tham gia chờ cho các chủ đề khác hoàn thành, nhưng trong trường hợp này, cả hai ngủ và tham gia làm điều tương tự? Sau đó, tại sao netbeans ném thận trọng?

+0

http://stackoverflow.com/questions/3535754/netbeans-java-new-hint-thread-sleep-called-in-loop này có thể giúp – pmu

+1

@prateek yeah, tôi thực sự đã thấy chuỗi đó trước khi đăng. Tuy nhiên, câu hỏi đó là một câu hỏi hoàn toàn khác (tôi biết nguyên nhân của sự thận trọng nhưng không biết tại sao nó lại xảy ra trong trường hợp này). cảm ơn cho đầu vào của bạn mặc dù! Nhiều đánh giá cao! –

Trả lời

28

Có sự khác biệt giữa join() và sleep(). join() sẽ đợi cho đến khi hết thời gian chờ hoặc chuỗi kết thúc. sleep() sẽ chỉ đợi khoảng thời gian được chỉ định trừ khi bị gián đoạn. Vì vậy, nó là hoàn toàn có thể cho tham gia() để trở về nhanh hơn nhiều so với thời gian quy định.

Lý do tại sao Netbeans cảnh báo bạn về giấc ngủ() và không phải về tham gia() chính xác là sự khác biệt đó. join() chờ đợi một cái gì đó có ý nghĩa trong khi ngủ() chỉ ngồi đó không làm gì cả. Nếu bạn không chờ đợi điều gì đó, vậy tại sao bạn lại muốn chờ đợi? Nó hiếm khi có ý nghĩa, do đó cảnh báo.

+0

à, tôi hiểu rồi! tôi tin rằng đây là câu trả lời duy nhất trả lời đúng qn của tôi. cảm ơn sự giúp đỡ của bạn sergey! –

5

Rằng chúng có thể được sử dụng để đạt được điều tương tự không có nghĩa là chúng bị lạm dụng theo cùng một cách. Mọi người thường lạm dụng Thread.sleep() khi họ thực sự cần sử dụng một khóa hoặc cái gì đó khối:

// 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; 
+0

cảm ơn sự giúp đỡ! tôi đoán sau đó qn của tôi sẽ được này-whats sự khác biệt ở đây giữa giấc ngủ và tham gia? trông không giống với tôi trong trường hợp này .. –

+1

Trong trường hợp của bạn, không có sự khác biệt; Netbeans chỉ đưa ra một cảnh báo cho 'sleep()'. –

+0

Tôi nghĩ rằng tham gia là tốt hơn so với việc sử dụng một khóa ... –

1

Đối với trường hợp này, tôi nghĩ rằng tham gia là lựa chọn tốt hơn so với sử dụng một khóa .. tham gia rất đơn giản và thanh lịch. Nhưng nếu bạn sử dụng khóa, bạn cũng nên sử dụng phương thức thông báo, và khối đồng bộ và tất nhiên bạn cần một đối tượng khóa ..

tham gia mẫu, gọi mã chủ đề;

t1.start(); 
System.out.println("waiting for thread t1"); 
t1.join(); 
System.out.println("thread t1 has finished its job"); 

mẫu khóa: mã chuỗi cuộc gọi;

Khóa đối tượng = 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(); 
    } 

}

Đây là chủ đề đang t1;

synchronized(lock) { 
     try { 
      System.out.println("doing heavy work"); 
      // ..... 
      lock.notify(); 
      }catch (InterruptedException ex) { 
       e.printStackTrace(); 
     } 

    } 
+0

cảm ơn sự giúp đỡ của bạn Gursel, được đánh giá cao. tôi đồng ý, ổ khóa chắc chắn là tốt hơn. nhưng qn của tôi đã ngủ và tham gia, và cả hai đều hoạt động giống nhau trong trường hợp cụ thể này. –

Các vấn đề liên quan