【问题标题】:this.start() doesn't run threat online serverthis.start() 不运行威胁在线服务器
【发布时间】:2018-02-22 12:02:57
【问题描述】:

我有下面的代码。当我在本地服务器(windows 10 和 Tomcat 8.0.47)上运行它时,它一切正常,在第二台计算机(ubuntu 和 Tomcat 8.5)上它运行 wothout 问题,只要我将它部署在外部服务器上(数字海洋,Linux 4.4.0-112-generic,Tomcat 8.5.27)它似乎并没有开始威胁。第二次运行启动代码时,它给出了 IllegalThreadStateException。 有什么建议可能是问题所在?

我的代码:

威胁:

public class Handler extends Thread {

protected DataExchange de;
protected boolean running;

public SearchRequestHandler(DataExchange de) {
    this.de = de;
    running = false;

}

    @Override
    public void run() {

        while (true) {
            synchronized (this) {
                   running = true;
                  //do Stuff



                try {
                    running = false;
                    this.wait();
                } catch (InterruptedException e) {
                    continue;
                }
            }
        }

    }

public void startIfNotStarted() {
        if (!this.isAlive()) {
            this.start();
        } else if (!running)
            synchronized (this) {
                {
                    this.notify();
                }
            }
    }

}

调用它的类:

public class controller {

    private static DataExchange de = new DataExchange();
    private static Handler h = new Handler(de);

public static void startThread(Info info) {

    de.addInfo(info);

    h.startIfNotStarted();

}
}

我第二次运行程序时的堆栈跟踪:

java.lang.IllegalThreadStateException java.lang.Thread.start(Thread.java:708) Handler.startIfNotStarted(SearchRequestHandler.java:235) controller.startThreat(Search_controller.java:71) 控制器.Controller.getMail(Controller.java:30) webServlet.SearchServlet.doPost(SearchServlet.java:110) javax.servlet.http.HttpServlet.service(HttpServlet.java:661) javax.servlet.http.HttpServlet.service(HttpServlet.java:742) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

【问题讨论】:

  • A) 遵循 java 命名约定。类名采用大写 - 因此不是 controller! B) 为什么你的控制器有 static 字段 C) 这里真正的问题是底层设计:你想在受控设置中准确调用 start() 。您似乎以某种方式重复调用 start 的事实(因此您引入了该方法)表明您的底层设计存在某种错误。您正在修复症状,而不是确保恰好有一个调用 start()。

标签: java multithreading tomcat servlets


【解决方案1】:
/**
 * This method is not invoked for the main method thread or "system"
 * group threads created/set up by the VM. Any new functionality added
 * to this method in the future may have to also be added to the VM.
 *
 * A zero status value corresponds to state "NEW".
 */
if (threadStatus != 0)
    throw new IllegalThreadStateException();

在您调用this.start(); 时,您的线程可能已经死了。请注意,您不能多次startThread 的同一个实例。

如果线程已启动且尚未死亡,则该线程处于活动状态。

另外,不需要使用running 字段。您可以通过Thread#getState查看Thread.State

if (this.getState() == State.NEW) {
    this.start();
}

你最好不要在条件下调用start。在控制器内进行一次适当的调用。 start 一个线程意味着 init 它,而不是 resume 它:

class Controller {

    private static Handler h = new Handler(de);

    static {
        h.start(); // it's guaranteed that the statement is called once
    }

}

【讨论】:

  • 即使在我从 tomcat 取消部署并部署应用程序后,也会发生这种情况吗?
  • @TimDJ,不,你会在任何地方调用h.start()吗?
  • startIfNotStarted在控制器中被调用,是不是可以多次调用?
  • 可以。这个想法是添加eveythime数据,它检查威胁是否已经在运行,如果没有启动它,以及它是否正在等待它将被中断以继续。
  • 我尝试重新启动 droplet,所以我知道所有旧实例肯定都会消失,但同样的问题仍然存在。
猜你喜欢
  • 2013-10-30
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-28
  • 2020-10-15
  • 2018-12-23
相关资源
最近更新 更多