【问题标题】:Illegal monitor state exception非法监视器状态异常
【发布时间】:2013-02-08 12:08:21
【问题描述】:

如何将轮询线程传递给另一个线程进行处理。 程序执行在一个控制器类中,它有一个 main 方法和一个线程池:

主类Controller

   public static void main(String[] args) throws InterruptedException {
    RunnableController controller = new RunnableController();

    System.out.println(incomingQueue.size());

    controller.initializeDb();
    controller.initialiseThreads();
    System.out.println("Polling");
    controller.initialUpdate(); 

}

具有轮询类线程的方法

 private void initialiseThreads()
{       
    try {

        threadExecutorRead = Executors.newFixedThreadPool(10);
PollingSynchronizer reader = new PollingSynchronizer(incomingQueue,dbConnection);   
        threadExecutorRead.submit(reader);

    }catch (Exception e){
        e.printStackTrace();
    }

}

具有处理器类线程的方法

    private void initialUpdate()
{
    RunnableController.outgoingQueue = incomingQueue;
    if((RunnableController.outgoingQueue)!= null){
        try {
            threadExecutorFetch = Executors.newFixedThreadPool(10);
        MessageProcessor updater = new MessageProcessor(outgoingQueue, dbConnection);
            threadExecutorFetch.submit(updater);
            DBhandler dbhandler = new DBhandler();
            dbhandler.updateDb(getOutgoingQueue());

        } catch (Exception e) {

        }
    }

}

轮询器类和控制器类

    public void run() {// Thread in the Poller class 
    int seqId = 0;
    while(true) {
        List<KpiMessage> list = null;
        try {
            list = fullPoll(seqId);
            if (!list.isEmpty()) {
                seqId = list.get(0).getSequence();
                incomingQueue.addAll(list);
                this.outgoingQueue = incomingQueue;             
                System.out.println("waiting");
                System.out.println("new incoming message");
                while(true){
                        wait(3000);
                        notify();
                }
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }
    }
}


          public void run() {// Second thread in the Processor Class
    synchronized (this){
        RunnableController.setOutgoingQueue(generate(outgoingQueue));
    }
    notify();
}   
 } 

我的任务和问题是:

1.控制器应该同时处理线程轮询器和处理器,它应该只调用轮询器和处理器线程

2.现在我的问题是如何让poller线程等待3秒并并行通知处理器。

我收到如下错误:

java.lang.IllegalMonitorStateException
    at java.lang.Object.wait(Native Method)
    at PollingSynchronizer.run(PollingSynchronizer.java:76)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
    at java.util.concurrent.FutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

这里如何实现异步处理?

【问题讨论】:

  • PollingSynchronizer 中的第 76 行是什么?也许你应该添加那个类。
  • @Zhedar 它是 Poller 类,我在 run 方法中向您展示了 poller 类中的线程...
  • 延迟是一次性交易还是您需要在轮询器中的每个处理循环执行一次?
  • @Babu - 从您当前的代码中,我看不出有任何理由说明您不能使用 sleep 来简单地暂停轮询线程约 3 秒。如果你绝对需要同步轮询器和处理器,我建议使用CyclicBarrier
  • @Babu - 好的,在这种情况下,您肯定想在所有三个线程之间使用同步辅助 - CyclicBarrier 将是我的选择。

标签: java multithreading exception asynchronous concurrency


【解决方案1】:

您需要先阅读this 之类的内容。不拿着对象的监视器就不能使用wait()。此外,乍一看,您似乎在多线程上下文中使用了非最终静态成员。尝试使该线程安全。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多