gpt4 book ai didi

java - 为什么在 Windows 上非守护线程终止后所有 SWT GUI 线程都关闭?

转载 作者:太空宇宙 更新时间:2023-11-04 03:47:29 24 4
gpt4 key购买 nike

我使用 SWT 打开主窗口,然后应用程序启动,然后窗口通过静态函数运行任务非守护线程。现在,窗口关闭,整个应用程序终止,在未知条件下终止任务线程。这是在 Windows 上发生的事情,而在 Linux 上运行时,线程继续在后台运行,检查自定义信号量并正确终止。是否有理由和/或解决方法可以在 Windows 平台上实现相同的行为?

给出一个看起来很奇怪的代码示例:

    package kg.clockworker;

public class Storage implements Runnable{
static int clockValue = 0;

@Override
public void run() {
for(clockValue=0; clockValue<1000; clockValue++)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

public static void main(String[] args) {
//ClockWorker.main(null);
Thread t = new Thread(new Storage());
//t.setDaemon(true);
t.start();

}

}

package kg.clockworker;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class ClockWorker extends Shell {

private Label label;

/**
* Launch the application.
* @param args
*/
public static void main(String args[]) {
Display display = Display.getDefault();
Realm.runWithDefault(SWTObservables.getRealm(display), new Runnable() {
public void run() {
try {
Display display = Display.getDefault();
ClockWorker shell = new ClockWorker(display);
shell.open();
shell.layout();
display.timerExec(40, new Runnable(){

@Override
public void run() {
shell.label.setText(Storage.clockValue+"");
display.timerExec(40, this);
}

});


Storage.main(null);

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}

/**
* Create the shell.
* @param display
*/
public ClockWorker(Display display) {
super(display, SWT.CLOSE | SWT.RESIZE | SWT.TITLE | SWT.APPLICATION_MODAL);

label = new Label(this, SWT.NONE);
label.setBounds(31, 20, 70, 20);
label.setText("0");
createContents();

}

/**
* Create contents of the shell.
*/
protected void createContents() {
setText("ClockWorker");
setSize(407, 132);

}

@Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
protected DataBindingContext initDataBindings() {
DataBindingContext bindingContext = new DataBindingContext();
//
return bindingContext;
}
}

在 Linux 上:然后 ClockWorker 关闭,应用程序仍在使用存储运行。可以实现终止代码。在 Windows 上:然后 ClockWorker 关闭,存储也关闭,可能处于未完成状态。

最佳答案

您需要了解Realm.runWithDefault()的作用;它同步调用 Runnablerun() 方法,当该 run() 返回时,调用代码将继续。关键是您在 main 方法中调用了 Realm.runWithDefault(),因此当 runWithDefault() 返回时,它会在 main() 中继续,从而结束并终止您的进程。

Runnable 中,您正在执行典型的 SWT 事件循环 (readAndDispatch()),该循环在 Shell 未释放时保持 Runnable 继续运行,但一旦您关闭 Shell,SWT 循环就会退出,从而结束您的 run() 方法(该方法又将控制权返回给 main(),如上所述)。

我不确定为什么这在 Linux 上会有所不同,因为 IIRC 这些规则在任何 JVM 上都是相同的。无论如何,如果您希望进程在 SWT shell 关闭后继续运行,则需要添加一些逻辑来实现这一点;基本上协调您拥有的两个线程。

关于java - 为什么在 Windows 上非守护线程终止后所有 SWT GUI 线程都关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27624597/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com