2017-03-16 65 views
0

我的情況,我引用了一些10 Thread秒,每個Thread必須等到Notifier類通知我要通知具體Thread S,我做的是我使用HashMapThread ID爲keyThread實例作爲值。後來在Notifier我試圖通過遍歷地圖map.get(threadId)它給出Thread實例通知它,我試圖打電話通知,但它是投擲IllegalmonitorException。我有疑問,怎麼同步HashMap或兩個WaiterNotifierThread ..是否可以在hashmap中存儲線程對象?

package com.cgi.sample.jms.requestor; 

import java.util.HashMap; 
import java.util.Map; 
import java.util.UUID; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class RequestorApplication { 
    private final Object lock = new Object(); 
    public static String correlationId; 

    public static String getCorrelationId() { 
     correlationId = UUID.randomUUID().toString(); 
     return correlationId; 
    } 

    public static void main(String args[]) throws Exception { 

     Map<Long, Thread> map = new HashMap<Long, Thread>(); 

     ExecutorService executor = Executors.newFixedThreadPool(5); 
     for (int i = 0; i < 2; i++) { 

      Waiter waiter = new Waiter(map); 

      executor.execute(waiter); 

      Notifier notifier = new Notifier(map); 
      executor.execute(notifier); 
     } 

     System.out.println("All the threads are started"); 
    } 
} 

class Waiter implements Runnable { 

    Map<Long, Thread> map; 
    ExecutorService executor = Executors.newFixedThreadPool(5); 

    public Waiter(Map<Long, Thread> map) { 
     this.map = map; 
    } 

    public void run() { 

     ExecutorService executor = Executors.newFixedThreadPool(5); 

     for (int i = 0; i < 2; i++) { 

      Runner instance = new Runner(); 

      System.out.println("Executing thread " + " with " + Thread.currentThread().getName()); 

      long threadId = Thread.currentThread().getId(); 

      String threadname = Thread.currentThread().getName(); 

      executor.execute(instance); 

      synchronized (map) { 

       map.put(threadId, Thread.currentThread()); 

       try { 
        instance.wait(); 
        System.out.println(threadname + " Thread entered into waiting state!!!"); 
        // Thread.currentThread().wait(); 
        System.out.println(threadname + " Thread woke up from wait!!!!!"); 

       } catch (InterruptedException e) { 

        e.printStackTrace(); 
       } 
      } 
     } 

    } 

} 

class Notifier implements Runnable { 

    Map<Long, Thread> map; 

    public Notifier(Map<Long, Thread> map) 

    { 
     this.map = map; 
    } 

    public synchronized void run() { 

     synchronized (map) { 

      for (Map.Entry<Long, Thread> entry : map.entrySet()) { 

       System.out.println("stored threads in map are--->" + map.get(entry.getKey())); 

       map.get(entry.getKey()).notify(); 

      } 

     } 
    } 
} 

class Runner implements Runnable { 

    public void run() { 
     System.out.println("runner invoked"); 

    } 
} 
+0

*「是否有可能在hashmap中存儲線程對象?」*是的,但那不是你的問題。你的問題是從一個不是該對象監視器所有者的線程的對象調用'notify'作爲['notify'文檔](http://docs.oracle.com/javase/8/docs/api /java/lang/Object.html#notify--)告訴你。由於您尚未顯示「通知」電話,因此我們無法幫助您。 –

+0

Hi.Crowder我打電話通知從Notifier類我修改了代碼你可以看看!!!!! – Tirumalesh

+0

你應該避免同步Thread對象,並且你絕對不應該調用'thread.wait()'或'thread.notify()'。原因是,'Thread'類自身使用'wait()'和'notify()'來達到自己的目的。一個好的經驗法則是永遠不要在_any_庫對象上同步。相反,你可以創建一個私有的最終對象lock = new Object();'然後對其進行同步。 –

回答

0

回答你的問題是:YES。因爲一個線程是一個對象,它可以存儲在一個HashMap中。

另一方面,@ T.J.Crowder告訴你,你錯用了通知的方式。這是因爲您正在調用通知沒有鎖定線程map.get(entry.getKey()).notify();)的對象。你應該代替調用該對象Runnerinstance.notify()),誰擁有的線程鎖notify,爲您的代碼顯示了我們:instance.wait();

首先!你必須syncrhonize塊對象instance誰將會阻止與wait方法,如螺紋:

synchronized(instance){ 
    try{ 
    instance.wait() 
    }catch(...) 
    { 
    //Do Something else 
    } 
} 

而且,調用該方法Runner對象的notify停止waitting,繼續線程,離開syncrhonized塊,是這樣的:

map.get(entry.getKey()).getRunnerInstance().notify();

但是,considere它,與你當前的代碼是如此難以實現這個技巧,因爲你必須重寫幾個部分,例如:鱈魚e你在哪裏使用住在for循環的上下文中的對象來阻塞線程

for (int i = 0; i < 2; i++) { 

    Runner instance = new Runner(); 
    //... 
    synchronized (map) { 

      map.put(threadId, Thread.currentThread()); 

      try { 
       instance.wait(); //You are blocking over a instance declared into the For Loop. 
      }catch(..){ 
       //.. 
      }; 
    } 

} 
+0

你能告訴我如何獲得地圖中線程實例的RunnerInstance。 – Tirumalesh

+0

檢查此鏈接:http://www.journaldev.com/1037/java-thread-wait-notify-and-notifyall-example –

相關問題