GVKun编程网logo

退出Swing应用程序时偶尔出现InterruptedException(swing退出按钮)

37

如果您想了解退出Swing应用程序时偶尔出现InterruptedException和swing退出按钮的知识,那么本篇文章将是您的不二之选。我们将深入剖析退出Swing应用程序时偶尔出现Interr

如果您想了解退出Swing应用程序时偶尔出现InterruptedExceptionswing退出按钮的知识,那么本篇文章将是您的不二之选。我们将深入剖析退出Swing应用程序时偶尔出现InterruptedException的各个方面,并为您解答swing退出按钮的疑在这篇文章中,我们将为您介绍退出Swing应用程序时偶尔出现InterruptedException的相关知识,同时也会详细的解释swing退出按钮的运用方法,并给出实际的案例分析,希望能帮助到您!

本文目录一览:

退出Swing应用程序时偶尔出现InterruptedException(swing退出按钮)

退出Swing应用程序时偶尔出现InterruptedException(swing退出按钮)

最近,我将计算机更新为功能更强大的计算机,并配备了四核超线程处理器(i7),因此可以使用大量实际并发。现在,我退出()正在开发的应用程序(带有Swing
GUI)时, 偶尔会 遇到以下错误System.exit(0)

Exception while removing reference: java.lang.InterruptedExceptionjava.lang.InterruptedException        at java.lang.Object.wait(Native Method)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)        at sun.java2d.Disposer.run(Disposer.java:125)        at java.lang.Thread.run(Thread.java:619)

好吧,鉴于它开始使用具有更多并发能力的硬件发生,并且与线程有关,并且偶尔发生,这显然是某种时机。但是问题是堆栈跟踪太短了。我只有上面的清单。它根本不包含我自己的代码,因此很难猜测该错误在哪里。

有没有人经历过这样的事情?任何想法如何开始解决它?

编辑:
由于使用退出Swing应用程序System.exit(0)可能是“不干净的”,但我不想将主机设置为,EXIT_ON_CLOSE因为我想确保退出应用程序时没有发生任何紧急情况,因此我添加了一种机制以使其执行dispose()调用之前的主要框架方法System.exit(0)。因此,它现在应该很干净,但偶尔仍会发生异常。它在System.exit(0)被调用之后发生;dispose()没问题。也就是说,它必须来自关闭钩子:

mainFrame.dispose(); // No problem! After this returns, all visible GUI is gone.// In fact, if there were no other threads around, the VM could terminate here.System.exit(0); // Throws an InterruptedException from sun.java2d.Disposer.run

我什至尝试Window通过遍历Window.getWindows()数组来显式处理所有s
(它包含无主Dialogs等),但没有区别。此问题似乎与“清除”没有关系(即在退出之前显式释放本机屏幕资源)。这是另外一回事,但是呢?

编辑2:
将默认关闭操作设置为EXIT_ON_CLOSE无差异。http://www.google.com/search?q=sun.java2d.Disposer.run(Disposer.java:125)发现了一些错误报告,因此也许这确实是Sun的Java2D实现中的错误。我可以想象像这样的错误会在很长一段时间内无法修复,因为实际上它们是无害的。关闭挂钩中的异常几乎不会伤害其他任何人。鉴于这是在GUI应用程序中发生的,除非将该异常stderr定向到控制台或日志,否则甚至不会注意到该异常。

答案1

小编典典

您的处置器在对remove()的调用中被阻止(删除下一个平台本机资源)。这意味着,当VM退出时,处置程序线程(守护程序线程)不会自然关闭(您应该期望这是因为要通过System.exit()终止它)。

您的应用程序中有一个非守护进程线程,当所有摆动窗口都已被处置后,该线程将阻止VM退出。

解决方案 :找到它并使其退出。

通常,如果已清除所有秋千应用程序的秋千应用程序,则该程序会正常退出,例如,此程序将弹出一个窗口,然后在关闭后退出(全部不调用System.exit()):

public static void main(String args[]) throws Exception {    JFrame jf = new JFrame();    jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);    jf.setVisible(true);}

您也可以尝试在退出之前运行垃圾收集器,只是为了踢。

&Thread线程:中断异常InterruptedException

&Thread线程:中断异常InterruptedException

方法讲解

Java Doc定义:
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. Occasionally a method may wish to test whether the current thread has been interrupted, and if so, to immediately throw this exception.
意思:当一个线程处于等待,睡眠,或者占用,也就是说阻塞状态,而这时线程被中断就会抛出这类错误。Java6之后结束某个线程A的方法是A.interrupt()。如果这个线程正处于非阻塞状态,比如说线程正在执行某些代码的时候,不过被interrupt,那么该线程的interrupt变量会被置为true,告诉别人说这个线程被中断了(只是一个标志位,这个变量本身并不影响线程的中断与否),而且线程会被中断,这时不会有interruptedException。但如果这时线程被阻塞了,比如说正在睡眠,那么就会抛出这个错误。请注意,这个时候变量interrupt没有被置为true,而且也没有人来中断这个线程。

 

  1. public static boolean interrupted();// 检测当前线程是否已经中断,此方法会清除中断状态,也就是说,假设当前线程中断状态为true,第一次调此方法,将返回true,表明的确已经中断了,但是第二次调用后,将会返回false,因为第一次调用的操作已将中断状态重新置为false了。
  2. public boolean isInterrupted() ;// 检测当前线程是否已经中断,此方法与上一方法的区别在于此方法不会清除中断状态。
  3. public void interrupt();//将线程中断状态设置为true,表明此线程目前是中断状态。此时如果调用isInterrupted()方法,将会得到true的结果。

结论:interrupt方法本质上不会进行线程的终止操作的,它不过是改变了线程的中断状态,将线程中断状态设置为true。而改变了此状态带来的影响是,部分可中断的线程方法(比如Object.wait, Thread.sleep,Object.join)会定期执行isInterrupted方法,检测到此变化,随后会停止阻塞并抛出InterruptedException异常,并且在抛出异常后立即将线程的中断标示位清除,即重新设置为false。

案例分析:
public class InterruptedException {
    public static void main(String[] args) throws Exception {
        System.out.println("初始中断状态:" + Thread.currentThread().isInterrupted());
        Thread.currentThread().interrupt();
        System.out.println("执行完interrupt方法后,中断状态:" + Thread.currentThread().isInterrupted());
 
 
        System.out.println("首次调用interrupted方法返回结果:" + Thread.currentThread().interrupted());
        System.out.println("此时中断状态:" + Thread.currentThread().isInterrupted());
        System.out.println("第二次调用interrupted方法返回结果:" + Thread.currentThread().interrupted());
        System.out.println("此时中断状态:" + Thread.currentThread().isInterrupted());
    }
}

结果:
初始中断状态:false
执行完interrupt方法后,中断状态:true
首次调用interrupted方法返回结果:true
此时中断状态:false
第二次调用interrupted方法返回结果:false
此时中断状态:false

分析:
InterruptedException异常的抛出并不是意味着线程必须得终止,它只是提醒当前线程有中断操作发生了,接下来怎么处理完全取决于线程本身,一般有3种处理方式:
1.“吞并”异常,当做什么事都没发生过。
2.继续往外抛出异常。
3.其它方式处理异常。其它处理异常的方式就有很多种了,停止当前线程或者输出异常信息等等。
在JDK1.0中,可以用stop方法来终止,但是现在这种方法已经被禁用了,改用interrupt方法。
Thread.interrupt()方法不会中断一个正在运行的线程。它的作用是,在线程受到阻塞时抛出一个中断信号,这样线程就得以退出阻塞的状态。更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),从而提早地终结被阻塞状态。

中断异常

public static void main(String[] args) {

    Thread thread = new Thread("thread") {
        @Override
        public void run() {
            while(true){
                try {
                    System.out.println("sleeping...");
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                    System.out.println("thread interrupted");
                    System.out.println(this.isInterrupted());
                }
            }
        }
    };
    thread.start();
    thread.interrupt();
}

结果:
sleeping...
thread interrupted
false
sleeping...
sleeping...
sleeping...
sleeping...
sleeping...
.
.
.
分析:
thread线程启动之后进行2秒的阻塞状态,这时候main线程执行thread线程的interrupt方法,设置thread线程的状态为可中断状态,
这个时候thread就会抛出异常InterruptedException,并且在抛出异常之后擦除调thread线程的中断状态又true为false。
public static void main(String[] args) {

    Thread thread = new Thread("thread") {
        @Override
        public void run() {
            while(true){
                try {
                    System.out.println("sleeping...");
                    Thread.sleep(2000);
                } catch (InterruptedException ex) {
                    System.out.println("thread interrupted");
                    System.out.println("before:" + this.isInterrupted());
                    Thread.currentThread().interrupt();
                    System.out.println("after:" + this.isInterrupted());
                }
            }
        }
    };
    thread.start();
    thread.interrupt();
}

结果:
sleeping...
thread interrupted
before:false
after:true
sleeping...
thread interrupted
before:false
after:true
.
.
.

分析:
thread线程启动之后进行2秒的阻塞状态,这时候main线程执行thread线程的interrupt方法,设置thread线程的状态为可中断状态,
这个时候thread就会抛出异常InterruptedException,并且在抛出异常之后擦除调thread线程的中断状态又true为false,所以before的状态为false,
这个时候又执行Thread.currentThread().interrupt()再一次将thread的中断状态设置为true,由于thread的while循环,thread进行sleep又抛出中断异常,这样循环往复。

总结:

在捕获InterruptedException异常之后如果只是想记录一条日志,那么就是不负责任的做法,因为在捕获InterruptedException异常的时候会将线程的中断标志置由trrue擦除掉改为false,这样就会导致方法其他链路获取该线程的中断状态有误,不能做出正确的响应。所以至少在捕获了InterruptedException异常之后,如果你什么也不想做,那么就将标志重新置为true,以便栈中更高层的代码能知道中断,并且对中断作出响应。

 

 

 


 

C3P0:java.lang.InterruptedException: sleep interrupted

C3P0:java.lang.InterruptedException: sleep interrupted

好好的就报异常了~~

警告: com.mchange.v2.resourcepool.BasicResourcePool@8fce95 -- Thread unexpectedly interrupted while performing an acquisition attempt.
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
	at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

com.intellij.openapi.application.RuntimeInterruptedException的实例源码

com.intellij.openapi.application.RuntimeInterruptedException的实例源码

项目:eddy    文件:EddyPlugin.java   
private static void checkLogging() {
  // if no logging preference saved,make the user select one
  final PropertiesComponent props = PropertiesComponent.getInstance();
  final String name = "com.eddysystems.Props.checkedLogging";
  String checked = props.getValue(name);

  log("logging state: " + checked);

  if (checked == null || !checked.equals("true")) {

    // we haven't checked before,check Now and save to Preferences
    final Object done = new Object();
    final Runnable showRunner = new Runnable() {
        @Override
        public void run() {
          final TOSDialog d = new TOSDialog();
          d.showAndGet();
          Preferences.getData().setLogPreference(d.logging());
          Preferences.save();
          synchronized (done) {
            done.notifyAll();
          }
        }
    };

    // go to dispatch to show dialog
    if (!ApplicationManager.getApplication().isdispatchThread()) {
      // we have to wait manually,because getting the current modality isn't a thing that 13 lets us do outside of
      // dispatch
      ApplicationManager.getApplication().invokelater(showRunner);
      try {
        synchronized (done) {
          done.wait();
        }
      } catch (InterruptedException e) {
        throw new RuntimeInterruptedException(e);
      }
    } else {
      showRunner.run();
    }
    props.setValue(name,"true");
  }
}

CountDownLatch InterruptedException

CountDownLatch InterruptedException

我正在使用CountDownLatch在两个线程之间同步初始化过程,我想知道它可能引发的InterruptedException的正确处理。

我最初编写的代码是这样的:

    private CountDownLatch initWaitHandle = new CountDownLatch(1);
    /**
     * This method will block until the thread has fully initialized,this should only be called from different threads  Ensure that the thread has started before this is called.
     */
    public void ensureInitialized()
    {
        assert this.isAlive() : "The thread should be started before calling this method.";
        assert Thread.currentThread() != this,"This should be called from a different thread (potential deadlock)";
        while(true)
        {
            try
            {
                //we wait until the updater thread initializes the cache
                //that way we know 
                initWaitHandle.await();
                break;//if we get here the latch is zero and we are done
            } 
            catch (InterruptedException e)
            {
                LOG.warn("Thread interrupted",e);
            }
        }
    }

这种模式有意义吗?基本上,忽略InterruptedException是一个好主意,只要一直等待它成功即可。我想我只是不了解这种情况会被打断的情况,所以我不知道我是否应该以不同的方式处理它们。

为什么会在这里引发InterruptedException,最佳的处理方式是什么?

今天关于退出Swing应用程序时偶尔出现InterruptedExceptionswing退出按钮的讲解已经结束,谢谢您的阅读,如果想了解更多关于&Thread线程:中断异常InterruptedException、C3P0:java.lang.InterruptedException: sleep interrupted、com.intellij.openapi.application.RuntimeInterruptedException的实例源码、CountDownLatch InterruptedException的相关知识,请在本站搜索。

本文标签: