Java线程在没有Exception/Throwable情况下停止



我有一个非常烦人的问题,我不能自己解决这个问题。

我有一个简单的JavaFX场景,只有2个按钮开始和结束线程。停止行动是不相关的,在这种情况下,因为我不能得到线程工作良好。actionListener看起来像:

EDIT1:找出了问题,这是不是线程特定的,这是对TimeServer的请求,看看这里:答案
感谢所有回答这个问题或阅读这个问题的人!:)

private FarmAction action = null;
@FXML
void btnStartListener(ActionEvent event) {      
Firefox ff = new Firefox();
ff.startBrowser();
BrowserAction browserAction = new BrowserAction(ff.getDriver(), ff.getJse());
browserAction.loginToGame(user, pass);
ObservableList<AttackCommand> list = (ObservableList<AttackCommand>) Serializer.deserialize(Constants.FILE_NAME_TESTPURPOSE);

if(action == null)
    action = new FarmAction(ff.getDriver(), ff.getJse(), list);
Thread run = new Thread(action);
try {
    run.start();
} catch (Exception e) {
    e.printStackTrace();
} catch (Throwable t) {
    t.printStackTrace();
 }
}   

注意:我正在使用Selenium框架来自动单击网站。

我的FarmAction类是这样的:

public class FarmAction implements Runnable{
private WebDriver driver;
private JavascriptExecutor jse;
private ObservableList<AttackCommand> attackList;
private boolean stop = false;
public FarmAction(WebDriver driver, JavascriptExecutor jse, ObservableList<AttackCommand> attackList) {
    this.driver = driver;
    this.jse = jse;
    for(AttackCommand ac : attackList)
    {
        ac.transferFromPropToAttributes();
    }
    this.attackList = attackList;
}

@Override
public void run() {
    ArrayList<Integer> unitIds = Constants.UNIT_ID_LIST_ALL;
    if(!driver.getCurrentUrl().equals(Constants.URL_TESTPURPOSE))
            driver.navigate().to(Constants.URL_TESTPURPOSE);
    int count = 0;
    while(true) { // Just let the Thread run for duration = lifetime of application
        System.out.println(count++); //count how often the thread runs into this while loop before terminating for no reason
        for(AttackCommand ac : attackList) {            
            for(int i = 0; i < unitIds.size(); i ++) {
                int unitKey = unitIds.get(i); // Momentane UnitID der Iteration                 
                if(ac.getUnits().containsKey(unitKey) && ( ac.getTurnBackTime() == 0 ||ac.getTurnBackTime() <= DateUtil.getActualServerTime())) // getActualServerTime is request against the timeserver de.pool.ntp.org
                {
                    String textfieldName = Constants.HASHMAP_TEXTFIELD_NAME_ALL_HTML_PLACE.get(unitKey);
                    WebElement textfield = driver.findElement(By.name(textfieldName));
                    textfield.sendKeys(String.valueOf(ac.getUnits().get(unitKey)));
                    WebElement textfieldCoordinates = driver.findElement(By.name(Constants.TEXTFIELD_NAME_HTML_PLACE_COODRINATESFORTARGET));
                    textfieldCoordinates.sendKeys(StringHelper.getPointAsString(new Point(ac.getXCoordinates(), ac.getYCoordinates())));

                    WebElement submitButton = driver.findElement(By.id(Constants.TA));
                    submitButton.click();
                    WebElement sndAttackSubmitButton = driver.findElement(By.name(Constants.SBM));
                    WebElement span = driver.findElement(By.className(Constants.CLASSNAME_TIME));
                    long duration = Long.parseLong(span.getAttribute(Constants.ATTRIBUTE_DURATION));
                    sndAttackSubmitButton.click();
                    ac.setStartTime(DateUtil.getActualServerTime());
                    ac.setDurationInSeconds(duration*1000);
                    ac.setTurnBackTime(ac.getStartTime()+ac.getDurationInSeconds());
                } 
            }
        }
    }
}}

正如你所看到的,我已经将thread .start()方法包装成一个用于Throwables和Exceptions的try-catch方法,但是如果线程无故停止,我不会得到任何Stacktrace。我期望一个StackOverFlow错误,但我没有捕捉到任何东西。

我的线程正在工作的循环数量是非常不同的。有时它在12点后停止,有时在370或59点后停止。所有值都是示例-每次都不同。

你知道我做错了什么吗?

提前感谢!

需要检查Thread类的run()方法内部是否有异常

调用start()方法后,创建的线程有自己的堆栈,这与主线程的堆栈不同,start()方法是从主线程的堆栈中调用的。

因此,在线程的run()方法中抛出的异常对于与start()方法相关的catch语句是不可见的。

好了,伙计们,我已经把问题解决了。这不是线程特定的,抱歉,但我已经学到了更多的线程,因为你的答案:)感谢你们每个人!

我把systemout放在每一条代码行后面,并发现在25次运行和冻结后,有两种可能的代码行,线程停止工作:

两个语句都使用了我的DateUtil.getActualServerTime()方法,如下所示:​

public static long getActualServerTime() {
    String TIME_SERVER = "de.pool.ntp.org";   
    NTPUDPClient timeClient = new NTPUDPClient();
    InetAddress inetAddress;
    long returnTime = 0;
    try {
        inetAddress = InetAddress.getByName(TIME_SERVER);
        TimeInfo timeInfo = timeClient.getTime(inetAddress);
        returnTime = timeInfo.getMessage().getTransmitTimeStamp().getTime();
    } catch (Exception e) {
        e.printStackTrace();
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return returnTime;
}

我使用的是apache.commons.net库。如果我只是返回aDate d = new Date(); return d.getTime();在我手动停止它之前,我的线程工作得很好,大约有60000个循环。

我在这里也没有得到Exception或Throwable。我会说在特定时间内对时间服务器有最大请求量之类的。我现在在网站上找不出来

正如@Immibis在评论中提到的,在thread.start()周围捕获异常是没有意义的,因为它会立即返回。

检查异常的一种方法是使用UncaughtExceptionHandler,它看起来像这样:

Thread run = new Thread(action);
run.setUncaughtExceptionHandler(
    new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            e.printStackTrace();
        }
    }
);
run.start();

我也有同样的问题,我的线程在没有任何异常/可抛出的情况下终止。

我有一个线程接受套接字(nio,但阻塞模式)。如果套接字以较慢的速度接收请求,那么这种方法可以很好地工作,但是当一次接收大量请求时,线程会停止。

我在linux中更改了一些选项,如mem [net.ipv4]。tcp_rmem net.core。wmem_default net.ipv4。Tcp_mem],可能是为了这个?

相关内容

  • 没有找到相关文章

最新更新