2011-12-28 62 views
2

之前,我有一堆代碼&處理器小,
調用notifyAll時,有時會產生性能問題(100毫秒),所以我想知道是什麼的線程當前正等待要釋放的對象。讓所有等待的對象線程調用notifyAll的

synchronized (obj){ 
//do some stuff.. 
obj.notifyall(); 
} 

我想打印所有等待該對象線程調用obj.notifyAll()

+0

如果您希望所有線程在通知之前停止等待,調用notifyAll()會有什麼意義?無論如何,我不認爲這是可行的使用Java同步,你可能必須發明一些鎖使用可用的鎖(以及一些障礙或其他東西來跟蹤它們)。 – Fredrik

+0

謝謝..接受我以前的問題..答案..,我沒有意識到..,我會照顧現在.., &我不希望以前的線程停止等待,我可能會調試那些線程..&檢查特定的線程是否有必要或不... –

回答

7

之前得到釋放的所有線程的資源等待着相同的條件?如果是,那麼你可以嘗試更換obj.notify()而不是obj.notifyAll,雖然它確實不被推薦。 AFAIK,沒有辦法「檢索」等待給定對象的所有線程的列表(儘管你可以通過編程方式獲得進程的線程轉儲並查看線程,但我相信這不是你在心神)。即使有,列出線程,然後與他們做「事情」肯定會花費更多的時間到notifyAll。另外,如果「處理器很小」,請嘗試限制生成的線程數,因爲沒有相當數量的「真實」線程,創建太多的線程通常是開銷。這樣,notifyAll不會喚醒一堆線程。

這裏是演示了與內聯註釋傾銷的線程狀態信息的小程序:

package net.sanjayts.test; 

import java.lang.management.ManagementFactory; 
import java.lang.management.ThreadInfo; 
import java.util.concurrent.TimeUnit; 

public class ThreadDumpTest { 

    public static void main(String[] args) throws Exception { 
     final Object lock = new Object(); 
     for (int i = 0; i < 6; ++i) { 
      final int cnt = i; 
      new DaemonThread(new Runnable() { 
       @Override 
       public void run() { 
        try { 
         // If counter is even, try to acquire common lock and then 
         // sleep. If odd, sleep without trying to acquire the lock. 
         // This way, if we do a thread dump, we'll see threads in 
         // different states (TIMED_WAIT for those sleeping threads 
         // and BLOCKED for those waiting for the common "lock". 
         if (cnt % 2 == 0) { 
          synchronized (lock) { 
           TimeUnit.MINUTES.sleep(1); // sleep 1 min 
          } 
         } else { 
          TimeUnit.MINUTES.sleep(1); // sleep 1 min 
         } 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, "mythread-" + cnt).start(); 
     } 
     ThreadInfo[] infos = ManagementFactory. 
       getThreadMXBean().dumpAllThreads(true, true); 
     for (ThreadInfo info : infos) { 
      System.out.println(info); 
      System.out.println("==========================="); 
     } 
     TimeUnit.SECONDS.sleep(2); 
    } 

} 

class DaemonThread extends Thread { 
    public DaemonThread(Runnable r, String name) { 
     super(r, name); 
     setDaemon(true); 
    } 
} 
+0

哦,我想列出它們只是爲了調試目的...,謝謝你的答案,我會嘗試打印所有的線程轉儲。這可以給我想法, ,因爲我有兩個項目之一是改變版本,&&我正在比較他們,我期望notifyall應該在這兩個地方花費相同的時間, 我認爲線程轉儲將解決問題。 ..將嘗試它... –

+0

我已經編輯了一個樣本片段的帖子,它將轉儲線程信息,其中包括線程的狀態以及「鎖定」信息(如果有的話)。祝你好運。 –

+0

會在JEE環境中工作嗎? –

1

您可以使用Thread.getAllStackTraces(),並打印出所有這一切都在等待的線程。