分布式系统中的非法状态监视器异常 [英] Illegal State Monitor Exception in distributed system

查看:125
本文介绍了分布式系统中的非法状态监视器异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的代码。它应该实现一种在分布式系统中同步呼叫的方式。这是我发送消息并等待确认的部分。网络和对等设备被认为是可靠的。

this is my code. It's supposed to implement a way of synchronizing calls in a distributed system. This is the part where i send the message and wait for acks. The network and the peers are supposed reliable.

我的问题与本地同步有关,因为它不断引发这种异常,我不明白为什么。

My problem though is related to local sync, because it keeps raising this exception and i cannot understand why.

Exception in thread "Thread-7" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:503)
at distributed.PeerManager.sendAllWithAck(PeerManager.java:212)
at distributed.TokenManager.onTokenReceived(TokenManager.java:67)
at communication.TokenMessage.execute(TokenMessage.java:21)
at distributed.ListenThread.run(ListenThread.java:38)
Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
    at java.lang.Object.notify(Native Method)
    at distributed.AckWaiter.run(AckWaiter.java:74)

以下是AckWaiter类:

Here's the AckWaiter class:

public class AckWaiter extends Thread {
    public int counter;
    PeerManager pm;
    Message m;
    public Object waiter;
    public int parentPort;

    public AckWaiter(PeerManager pm, Message m, int n,int parentPort) {
        counter = n;
        this.pm = pm;
        this.m = m;
        this.parentPort=parentPort;
        waiter=new Object();
    }

    public synchronized void notifyAck() {
        counter--;
            notify();

    }

    @Override
    public synchronized void run(){
        pm.sendAllExceptMe(m);

        try {
            BufferedReader inFromClient=new BufferedReader(new
                    InputStreamReader(pm.listener.socketMap.get(parentPort).getInputStream()));
            while(counter>0){
                    wait(100);
                    Message m=CustomMarshaller.getCustomMarshaller().unmarshal(inFromClient.readLine());
                    if(m==null){
                        continue;
                    }
                    m.execute(pm);
                }
                } catch (IOException | InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } 


        waiter.notify();
        return;
    }
}

这是应该阻塞线程的调用

and here's the call supposed to block the thread

public synchronized void sendAllWithAck(Message m){
    if(aw!=null){
        throw new RuntimeException();
    }
    aw=new AckWaiter(this,m,connectionList.size()-1,m.sender.getPort());
    aw.start();
    try {
        aw.waiter.wait();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    aw=null;
}

'sendAllWithAck'应该启动AckWaiter线程,在对象'waiter'上等待

'sendAllWithAck' should start a AckWaiter Thread, wait on the object 'waiter' that will be notified when i receive 'n' ACKs.

当接收到ACK消息时,通信层将调用 notifyAck方法。

The 'notifyAck' method is called by the communication layer when an ACK message is received.

AckWaiter本身就是一个线程,因为负责读取套接字的线程可以调用 sendAllWithAck。我有n个对等方,每个对等方都有一个开放的套接字(每个线程都有一个用于处理入站消息的线程),因此,如果我等待ACK来响应收到的消息,我将无法从该消息中读取ACK。 peer(parentPort是该对等方的标识符,因此我可以定期检查此线程内的ACK)。

AckWaiter is a thread on his own because 'sendAllWithAck' could be called by a thread in charge of reading from a socket. I have n peers and every peer has an open socket (with a Thread handling inbound messages) for every other peer, so if i wait for ACKs in response to a message received, i wouldn't be able to read the ACK from that one peer (parentPort is the identifier of that peer so i can periodically check for ACKs inside this thread).

如果此异常是由于以下原因,我愿意修改自己的体系结构一个结构性问题,但是我不知道不修改我的通信层就无法处理,这会很痛苦。

I'm open to modify my architecture if this exception is due to a structural problem but i have no idea to handle it differently without modify my communication layer, and that would be a pain.

推荐答案

方法 wait() notify() notifyAll()必须在 synchronized 块中。并且run方法仅由一个线程访问(因此不需要同步),并且在ListenThread中存在异常。

Methods wait(), notify() and notifyAll() must be in synchronized block. And run method is only accessed by one thread (so it doesn't need to be synchronized) and exception was in ListenThread.

这篇关于分布式系统中的非法状态监视器异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆