首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Java中使用等待/通知机制终止生产者-消费者线程

在Java中使用等待/通知机制终止生产者-消费者线程
EN

Stack Overflow用户
提问于 2013-06-13 21:03:56
回答 1查看 573关注 0票数 0

我维护的应用程序(通过许多编码器)使用等待/通知机制实现了Producer-Consumer problematic。

使用者在应用程序的“服务器”端等待消息,然后在“客户端”端将消息转发到LDAP服务器。

问题是当建立/终止多个连接时。生产者线程只会保持倍增,并且永远不会在应该终止的时候被终止。

当连接终止时,生产者/消费者线程也应该终止。在建立/终止大量连接的情况下,内存使用率会变得非常惊人。

代码:

代码语言:javascript
复制
class Producer extends Thread {
    public void run() {
        long previous = 0;
        long last = 0;
        long sleeptime = 1;

        while (alive) {
            try{
                last = System.currentTimeMillis();

                byte[] aux;
                if ((aux = cliente.readmessage()) != null){

                    sleeptime = 1;
                    previous = last;

                    synchronized (list) {
                        while (list.size() == MAX)
                            try {
                                list.wait();
                            } catch (InterruptedException ex) {
                            }
                        list.addFirst(new Messagetimestamped(aux, System
                                .currentTimeMillis()));
                        list.notifyAll();
                    }
                }
                else{
                    if (last-previous > 1000)
                        sleeptime = 1000;
                    else
                        sleeptime = 1;
                    sleep(sleeptime);
                }
            }
            catch (Exception e){
                if (lives()){
                    System.out.println("++++++++++++++++++ Basic Process - Producer");
                    kill();
                    nf.notify(false, processnumber);
                }
                return;
            }
        }
    }
}


class Consumer extends Thread{

    public void run() {
        while (alive) {
            byte[] message = null;
            Messagetimestamped  mt;
            synchronized(list) {
                while (list.size() == 0) {
                    try {
                        list.wait(); //HANGS HERE!
                        if (!alive) return;
                        sleep(1);
                    }
                    catch (InterruptedException ex) {}
                }
                mt = list.removeLast();
                list.notifyAll();
            }
            message = mt.mensaje;

            try{
                long timewaited = System.currentTimeMillis()-mt.timestamp;

                if (timewaited < SLEEPTIME)
                    sleep (SLEEPTIME-timewaited);

                if ( s.isClosed() || s.isOutputShutdown() ){
                    System.out.println("++++++++++++++++++++ Basic Process - Consumer - Connection closed!(HLR)");
                    kill();
                    nf.notify(false, processnumber);
                }
                else {
                    br.write(message);
                    br.flush();
                }
            } catch(SocketException e){
                return;
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

基本上,在alive设置为false之后,Producer实际上会被终止。消费者不需要,它只是停留在list.wait()系列上。显然,list.notify() (或list.notifyAll()?)Producer在终止后不会交付,因此消费者永远不会检查alive布尔值。

如何用尽可能少的修改来解决这个问题?

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2013-06-13 21:08:08

我只会使用一个ExecutorService,它会包装队列,管理你的线程,并为你处理关机。如果你这样做了,几乎所有的代码都会消失。

但为了回答你的问题,我建议你送一颗毒丸。一个特殊的对象,当消费者收到它时,它将被关闭。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17087789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档