1
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();
            }
        }       
    }
4

2 回答 2

3

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

new SerialReader(event, serialPort,mode);

请求SerialReader创建一个新的,但在构造函数中你这样做:

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

event一个在哪里ServletContextEvent。调用setAttribute它会触发对 servlet 上下文中所有属性侦听器的通知。您使用以下代码配置了这样的侦听器:

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

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

我不能 100% 确定您要通过侦听器完成什么,但您可能希望在其中生成消息发送线程而不是像现在这样在外部生成。

于 2013-03-06T14:14:36.497 回答
1

这是什么:

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

为什么不

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

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

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

但这是一个肮脏的黑客

于 2013-03-06T14:03:27.227 回答