产生线程主线程停止后?

时间:2013-03-06 13:34:56

标签: java multithreading

public void contextInitialized(final ServletContextEvent event) {   
    try {
        System.out.println("start thread");
        Thread thread = new Thread(new SerialReader(event, serialPort,mode));
        thread.start();
    } catch (Exception e1) {
        e1.printStackTrace();
    }

    System.out.println("thread engaged");
}

即使很难在运行此代码时也没有错误;永远不会打印“线程参与”。什么可以阻止主线程继续运行?

我用

替换它测试了这个
            Thread thread = new Thread(new Runnable(){
                public void run(){
                    try {
                        Thread.sleep(1000);
                        System.out.println("OUTPUT");
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                };  


            });

完美无缺。

编辑:构造函数中唯一发生的事情是

private BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
public SerialReader(ServletContextEvent event, String port, int mode) throws Exception {
   if (mode==1){
   System.out.println("**Mode 1**");
   } else {//mode is 1
   }
   event.getServletContext().setAttribute("serialPortData", queue);
}

edit2 :( servlet上下文监听器)

 private static final String SHUTDOWN_REQ = "SHUTDOWN";
    public void attributeAdded(ServletContextAttributeEvent event) {

        queue = (BlockingQueue<String>) event.getServletContext().getAttribute("serialPortData");

        //we always get a null here on first try that's why I added null check
        if (queue == null){
            System.out.println("Queue is empty");
        } else {
            String item;
            try {
                //blocks while queue is empty
                while ((item = queue.take()) != SHUTDOWN_REQ) {
                    System.out.println("*******WEB*******"+item+"*******");
                    //TODO Broadcast message to connected clients
                }
            } catch (InterruptedException e) {
                System.out.println("queue error");
                //e.printStackTrace();
            }
        }       
    }

2 个答案:

答案 0 :(得分:3)

您正在阻止自己的代码。这个表达式:

new SerialReader(event, serialPort,mode);

请求创建新的SerialReader,但在构造函数中执行此操作:

private BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
event.getServletContext().setAttribute("serialPortData", queue);

eventServletContextEvent的位置。在其上调用setAttribute会触发对servlet上下文中所有属性侦听器的通知。你有这样一个配置了这个代码的监听器:

else {
    try {
        //blocks while queue is empty
        while ((item = queue.take()) != SHUTDOWN_REQ) 

但是,执行此代码时,您的队列不为空,因此您可以在 调用线程 上连续轮询队列以从中获取项目。这就是为什么你的构造函数永远不会返回。

我不是百分之百确定你要用侦听器完成什么,但是你可能想要在其中发送消息 in ,而不是外部你现在的方式

答案 1 :(得分:1)

这是什么:

(item = queue.take()) != SHUTDOWN_REQ

为什么不

!(item = queue.take()).equals(SHUTDOWN_REQ)

或者你可以进行流动,并继续比较字符串!= / ==:

private static final String SHUTDOWN_REQ = "SHUTDOWN".intern();

但这是一个肮脏的黑客