[英]is it possible to store thread objects inside hashmap?
我有一個場景,我調用了大約10個Thread
,並且每個Thread
都必須等到Notifier
類通知我要通知特定的Thread
,我正在做的事情是我正在使用HashMap
並將Thread
id作為key
並將Thread
實例作為值。 稍后在Notifier
我試圖通過遍歷提供Thread
實例的映射map.get(threadId)
來通知它,並且嘗試在其上調用notify,但是它拋出IllegalmonitorException
。 我不確定在Waiter
和Notifier
類中要同步HashMap
還是Thread
。
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");
}
}
您的問題的答案是: 是 。 因為線程是對象,所以可以將其存儲到HashMap中。
否則,@ TJCrowder告訴您,您使用通知的方式是錯誤的。 這是因為您正在通過沒有線程鎖的對象 ( map.get(entry.getKey()).notify();
)調用通知 。 而不是您應該調用對象Runner
( instance.notify()
)的notify
,該對象具有線程鎖定,如您的代碼所示: instance.wait();
首先! 您必須與對象instance
同步阻塞對象,該對象instance
將使用wait
方法阻塞線程,例如:
synchronized(instance){
try{
instance.wait()
}catch(...)
{
//Do Something else
}
}
然后,調用對象Runner
notify
方法停止等待並繼續執行線程並離開syncrhonized塊,如下所示:
map.get(entry.getKey()).getRunnerInstance().notify();
但是,考慮一下,當前的代碼很難實現此技巧,因為您必須重寫幾個部分,例如: 您正在使用對象的代碼,該對象位於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(..){
//..
};
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.