写了个同步的东东但是一直抛异常:
java.lang.IllegalMonitorStateException
at java.lang.Object.notifyAll(Native Method)
at org.platform.webservice.MessageControl.SendMessage(MessageControl.java:79)
at org.platform.servlet.RequestSevlet.doPost(RequestSevlet.java:62)
at org.platform.servlet.RequestSevlet.doGet(RequestSevlet.java:42)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
能帮忙看下什么问题吗?
package org.platform.webservice;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.platform.util.SysConfigManager;
import com.coreframework.util.Asserter;public class MessageControl {

private static Map<String, SynchronizedObj> map = new Hashtable<String, SynchronizedObj>();

private static Map<String,BlockingQueue<String>> keymap = new Hashtable<String, BlockingQueue<String>>();

public static String GetMessage(WSRequest request) {
String hosid = request.getHosid();
String uuid = UUID.randomUUID().toString();

BlockingQueue<String> poollist = keymap.get(hosid);

if(null == poollist){
poollist = new LinkedBlockingQueue<String>();
keymap.put(hosid, poollist);
}
String poolUid = hosid+uuid;

poollist.add(hosid+uuid);

SynchronizedObj obj = new SynchronizedObj(poolUid);

map.put(poolUid, obj);

try {
long timeout = SysConfigManager.getInstance().getWSMesageTimeOut();
synchronized (obj) {
obj.wait(timeout);
String result = obj.getResult()!=null?obj.getResult().toString():null;
if(null != result && !"".equals( result )){
return result;
} else {
return "null";
//return getResponse( request.getHosid(), request.getApi(), -123, "请求超时!请重新发起请求.").asXml(false);
}
}
} catch (Exception e) {
e.printStackTrace();
return e.getLocalizedMessage();
//return getResponse( request.getHosid(), request.getApi(), -123, "请求异常!请重新发起请求.").asXml(false);
}
}
/***
 * <Api>BOSS-GH</Api>
 * <UUID>aaaaaaaaaa</UUID>
 * <Request>
 *  <Name>a</Name>
 * </Request>
 * @param hosid
 * @param args
 * @return
 * @throws Exception
 */
public static String SendMessage(String hosid,String args) throws Exception{

String requestUUID = UUID.randomUUID().toString();
String key = requestUUID + hosid;

BlockingQueue<String> pools = keymap.get(hosid);
Asserter.notNull(pools, "没有请求连接.HosID = "+ hosid);
Asserter.notEmpty(pools, "连接池没有连接.");
String hospool = pools.peek();
SynchronizedObj object = map.get(hospool);

ResponseMessage msg = new ResponseMessage();
msg.setUuid(key);
msg.setMessage(args);

object.setResult(msg);
object.notifyAll();

SynchronizedObj obj = new SynchronizedObj(key);
map.put(key, obj);
synchronized (obj) {
try {
obj.wait(20*1000);
return obj.getResult().getResult().toString();
} catch (InterruptedException e) {
e.printStackTrace();
return null;
}
}
}

public static String ReturnValue(WSRequest request){
String upuuid = request.getUpMessageID();
SynchronizedObj obj = map.get(upuuid);

ResponseMessage msg = new ResponseMessage();
msg.setMessage(request.getChildValue("name")); obj.setResult(msg);
obj.notify();
return "ok";
}
 private static ResponseMessage getResponse(String id, String api, int code, String message)
 {
ResponseMessage rsp = new ResponseMessage();
rsp.addChild("ID", id);
rsp.addChild("Api", api);
rsp.addChild("Response", "Code", Integer.valueOf(code));
rsp.addChild("Response", "Message", message);
    return rsp;
 }  public static SynchronizedObj getHosRequestObj(String hosid){
 SynchronizedObj obj = map.get(hosid);
 return obj;
 }
}

解决方案 »

  1.   

    调用GetMessage方法时把对象存到map 中 然后锁住,然后调用SendMessage方法时把该对象释放锁,可是为什么会抛出这个异常呢?
      

  2.   


     object.notifyAll();
    这句的object对象,没有任何代码以这个对象做同步监视器。也不在同步代码块里。
      

  3.   

    object.notifyAll();这句话,应该放在 synchronized 块中,保证其所有权,类似:synchronized(object) { 
      object.notifyAll();
    }
      

  4.   

    api是这么解释这个异常的:
    抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
    一般在不正确使用了wait/notify方法时会抛出这个异常。或者说在不拥有对象锁标记的情况下,使用了wait或notify就是抛个这异常。你的错误信息也指出了问题所在,应该是这一行调用。object.notifyAll();这行代码应该在一个包含了锁的一个同步块里。
      

  5.   

    http://www.ticmy.com/?p=219