2012-04-15 86 views
1

我正在瀏覽線程,並且我讀到notify()方法用於向同一對象的等待池中正在等待的線程中的一個且僅有一個線程發送信號。方法notifyAll()的工作方式與notify()相同,只是它將信號發送給所有等待Object的線程。關於通知()

現在我的問題是,假設我有5個線程和一個主線程,所以最初主線程啓動,然後另外5個線程啓動。現在我想只發送通知給第三個線程。使用notify()怎麼可能,因爲在這裏我只向第三個線程發送通知?請指教。

回答

3

如果您想要通知特定線程,請將其wait()放在不同的對象上,並且在該對象上調用notify()

+1

Thanks非常感謝,請您出示一個小程序,讓理解更加清晰..預先感謝..!1 – Neera 2012-04-15 04:13:03

+2

@ user1334074:請接受一個答案,並做一點工作。 – Jayan 2012-04-15 05:23:41

+0

@ user1334074答案似乎對我很清楚。任何有能力的Java程序員都應該能夠把它變成代碼。 – EJP 2012-04-15 05:49:15

3

ReentrantLock類爲您提供比​​關鍵字更多的細粒度控制,允許每個對象有多個等待設置。

您可以使用ReentrantLock.newCondition()ReentrantLock獲得多個Conditions。線程然後可以調用Condition.await()(功能類似於Object.wait())並且將阻塞,直到另一個線程調用Condition.signal()(在功能上類似於Object.notify())。

區別在於您可以爲單個ReentrantLock創建多個Conditions。因此,您可以爲每個Thread創建一個Condition,並根據您想要喚醒的Thread對應的條件呼叫signal()


下面是一個簡單的示例代碼,它演示了上述情況。它創建了5個Threads,它們都在等同於ReentrantLock的不同Conditions。主線程然後調用signal()來喚醒Threads中的特定一個。

import java.util.concurrent.locks.Condition; 
import java.util.concurrent.locks.ReentrantLock; 

public class ReentranLockTest 
{ 
    public static void main(String[] args) 
    { 
     final ReentrantLock lock = new ReentrantLock(); 

     int numThreads = 5; 

     Condition[] conditions = new Condition[numThreads]; 

     // start five threads, storing their associated Conditions 
     for (int i = 0; i < numThreads; i++) 
     { 
      final int threadNumber = i; 

      System.out.printf("Started thread number %d%n", threadNumber); 

      // to create a Condition we must lock the associated ReentrantLock 
      lock.lock(); 
      try 
      { 
       final Condition condition = lock.newCondition(); 
       conditions[i] = condition; 

       // start the worker Thread 
       (new Thread() 
       { 
        @Override 
        public void run() 
        { 
         // wait on the Condition 
         // to do so we must be holding the 
         // associated ReentrantLock 
         lock.lock(); 
         try 
         { 
          condition.await(); 
         } 
         catch (InterruptedException e) 
         { 
          e.printStackTrace(); 
         } 
         finally 
         { 
          lock.unlock(); 
         } 

         // print something when signal() 
         // is called on our Condition 
         System.out.printf("Thread number %d woke up!%n", threadNumber); 
        } 
       }).start(); 
      } 
      finally 
      { 
       lock.unlock(); 
      } 
     } 

     // acquire the ReentrantLock and call 
     // Condition.signal() to wake up Thread number 3  
     lock.lock(); 
     try 
     { 
      System.out.printf("Waking up Thead number %d%n", 3); 

      conditions[3].signal(); 
     } 
     finally 
     { 
      lock.unlock(); 
     } 
    } 
} 

這應該打印以下:

發起者線程編號0

發起者線程數1

發起者線程數2

發起者線程數3

開始線程數4

醒來的tHead 3號

螺紋數3醒了!

+0

Thnks很多..! – Neera 2012-04-15 07:07:26

+0

你也可以請建議一個教程或URL,其中的鎖和reeneterant鎖的概念正確解釋.. !! – Neera 2012-04-15 07:10:53

+0

@ user1334074 Oracle擁有一系列官方Java教程。這是[Concurrency]上的一個開頭(http://docs.oracle.com/javase/tutorial/essential/concurrency/)。這裏有很多很好的信息,包括[Lock Objects](http://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html)上的一個頁面。 – ulmangt 2012-04-15 15:22:07