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 :(サーブレットコンテキストリスナー)

 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と、サーブレットコンテキスト上のすべての属性リスナーへの通知がトリガーされます。このようなリスナーは、次のコードで構成されています。

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

ただし、このコードが実行されたときにキューはnullではないため、呼び出し元のスレッドでキューを継続的にポーリングして、キューからアイテムを取得します。そのため、コンストラクターは決して戻りません。

リスナーで何を達成しようとしているのかは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 に答える