Java 为什么非守护进程线程被终止,然后所有SWT GUI线程都在Windows上关闭?

Java 为什么非守护进程线程被终止,然后所有SWT GUI线程都在Windows上关闭?,java,linux,eclipse,multithreading,swt,Java,Linux,Eclipse,Multithreading,Swt,我使用SWT打开主窗口,然后应用程序启动,然后窗口通过静态函数运行任务非守护进程线程。现在,窗口关闭,整个应用程序终止,在未知条件下终止任务线程。这是在windows上发生的事情,在Linux上运行时,线程在后台继续运行,检查自定义信号量并正确终止。 在Windows平台上达到相同行为是否有原因和/或解决方法 给出一个看起来很奇怪的代码示例: package kg.clockworker; public class Storage implements Runnable{

我使用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;
    }
}
kg.clockworker包装;
公共类存储实现可运行{
静态int clockValue=0;
@凌驾
公开募捐{

对于(clockValue=0;clockValue您需要了解
Realm.runWithDefault()
的功能;它同步调用
Runnable
run()
方法,当
run()
返回时,调用代码将继续。关键是您拥有对
Realm.runWithDefault()的调用
在main方法中,因此当
runWithDefault()
返回时,它将在
main()
中继续,从而结束进程

Runnable
中,您正在执行典型的SWT事件循环(
readAndDispatch()
),该循环在
Shell
未被释放时保持
Runnable
运行,但在关闭
Shell
后,SWT循环退出,从而结束
run()
方法(这反过来又将控制权返回到
main()
,如上所述)


我不知道为什么这在Linux上会有不同的工作方式,因为IIRC这些规则在任何JVM上都是相同的。在任何情况下,如果你想在SWT外壳关闭后继续进程,你需要添加一些逻辑来做到这一点;基本上在你拥有的两个线程之间进行协调。

共享你的代码?为什么你认为在Linux上你有信号量tc?您是否尝试过使用try/finally或runtime shutdown钩子?是否尝试过将其添加到close listener?问题不是手动关闭线程,而是在windows上自动终止,然后所有GUI都关闭。我希望以Linux方式关闭它:在信号量上手动关闭它,即变量更改,正确释放资源,但它是down as all GUI closed.Realm.runWithDefault部分稍后由Eclipse绑定添加。最初存储主方法直接从主窗口的主方法运行。这并不重要;它的行为就像
run()
方法中的代码直接在
main()
方法中一样。