Поток Java застрял с вызовом уведомления

я застрял с этим кодом, и я думаю, что упускаю что-то действительно важное. когда поток запущен, я могу добавить сообщение в вектор, но когда он вызывает уведомление, кажется, что getNextMessageFromQueue() продолжает ждать.

Я блокирую переменные messages?

Спасибо за вашу помощь.

Мой класс диспетчера, который отправляет все сообщения моим клиентам:

private Vector<Message> messages = new Vector<Message>(); 

public synchronized void addMessage(Message message) {
    messages.add(message);
    notify(); 
}

private synchronized Message getNextMessageFromQueue() throws InterruptedException { 
    while (messages.size() < 1) {
        wait(); 
    }

    Message message = (Message) messages.get(0); 
    messages.removeElementAt(0);

    return message; 
}

private void sendMessageToAllClients(Message message) {     
    for (int i=0; i < clients.size(); i++) { 
        Client client = (Client) clients.get(i); 
        client.sendMessage(message); 
    } 
}

public void run() { 
    try { 
        while (true) { 
            Message message = getNextMessageFromQueue(); 
            sendMessageToAllClients(message); 
        } 
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    } 
}

Здесь клиентский класс:

private Socket socket;

private ObjectOutputStream out;
private ObjectInputStream in;

public Client(Socket s) throws IOException {
    socket = s;

    out = new ObjectOutputStream(socket.getOutputStream());
    in = new ObjectInputStream(socket.getInputStream());
}

public Socket getSocket() {
    return socket;
}

public void sendMessage(Message message) { 
    try {
        out.writeObject(message);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }           
}

Вот основной вызов addMessage :

Message message = new Message();
message.setMessage("Welcome to " + client.getSocket().getLocalAddress() + ":" + client.getSocket().getPort());

dispatcher.addMessage(message);

person user1952589    schedule 06.01.2013    source источник
comment
Есть ли какой-либо другой вызов wait() где-то еще? Вы не показываете нам полный код. Может ли вызов client.sendMessage() заблокироваться? Почему синхронизируется функция sendMessageToAllClients()? Он не использует вектор.   -  person JB Nizet    schedule 06.01.2013
comment
@ user1952589 - Тогда, пожалуйста, опубликуйте и этот код.   -  person Mike    schedule 06.01.2013
comment
код добавлен, спасибо за ваши ответы   -  person user1952589    schedule 06.01.2013
comment
Почему бы не использовать ArrayBlockingQueue взять()/положить()? (Вектор является общим, очередь может быть более подходящей)   -  person ggrandes    schedule 06.01.2013
comment
Я помню, что был вопрос и ответ, в котором говорилось, что мы должны избегать synchronized методов, и приводился пример, но я просто не могу найти его сейчас   -  person Alvin Wong    schedule 06.01.2013
comment
можете ли вы напечатать что-нибудь для консоли сразу после строки wait, чтобы увидеть, получает ли поток уведомление?   -  person Mikita Belahlazau    schedule 06.01.2013
comment
Было бы полезно, если бы вы привели простой полный пример, демонстрирующий проблему и с которым мы могли бы поэкспериментировать.   -  person NPE    schedule 06.01.2013
comment
@ Элвин Вонг, я думаю, что в более общем плане речь идет о синхронизации вокруг this (что и делает синхронизация на уровне метода), потому что клиенты могут захотеть синхронизироваться с вашим объектом и, таким образом, неохотно вмешиваться в вашу собственную блокировку.   -  person ignis    schedule 06.01.2013
comment
Можете ли вы попробовать notifyAll() вместо notify().   -  person JoG    schedule 06.01.2013
comment
@user1952589 user1952589 Вы сделали отладку?   -  person Mary Ryllo    schedule 06.01.2013
comment
@ user1952589 Вы решили свою проблему?   -  person Mary Ryllo    schedule 06.01.2013


Ответы (1)


Думаю, у вас ошибка в строке in = new ObjectInputStream(socket.getInputStream()); Удалите ее, если она не нужна, или перестройте другим способом. Прочитайте это Сокеты Java: программа останавливается на socket.getInputStream() w /о ошибка?

Чтобы понять, является ли ваш inputData пустым, используйте - socket.getInputStream(). available(), он возвращает размер входных байтов.

person Mary Ryllo    schedule 06.01.2013