如果您想了解退出Swing应用程序时偶尔出现InterruptedException和swing退出按钮的知识,那么本篇文章将是您的不二之选。我们将深入剖析退出Swing应用程序时偶尔出现Interr
如果您想了解退出Swing应用程序时偶尔出现InterruptedException和swing退出按钮的知识,那么本篇文章将是您的不二之选。我们将深入剖析退出Swing应用程序时偶尔出现InterruptedException的各个方面,并为您解答swing退出按钮的疑在这篇文章中,我们将为您介绍退出Swing应用程序时偶尔出现InterruptedException的相关知识,同时也会详细的解释swing退出按钮的运用方法,并给出实际的案例分析,希望能帮助到您!
本文目录一览:- 退出Swing应用程序时偶尔出现InterruptedException(swing退出按钮)
- &Thread线程:中断异常InterruptedException
- C3P0:java.lang.InterruptedException: sleep interrupted
- com.intellij.openapi.application.RuntimeInterruptedException的实例源码
- CountDownLatch InterruptedException
退出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
(它包含无主Dialog
s等),但没有区别。此问题似乎与“清除”没有关系(即在退出之前显式释放本机屏幕资源)。这是另外一回事,但是呢?
编辑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
方法讲解
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,而且也没有人来中断这个线程。
public static boolean interrupted();
// 检测当前线程是否已经中断,此方法会清除中断状态,也就是说,假设当前线程中断状态为true,第一次调此方法,将返回true,表明的确已经中断了,但是第二次调用后,将会返回false,因为第一次调用的操作已将中断状态重新置为false了。public boolean isInterrupted() ;
// 检测当前线程是否已经中断,此方法与上一方法的区别在于此方法不会清除中断状态。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方法。
中断异常
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
好好的就报异常了~~
警告: 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的实例源码
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的正确处理。
我最初编写的代码是这样的:
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应用程序时偶尔出现InterruptedException和swing退出按钮的讲解已经结束,谢谢您的阅读,如果想了解更多关于&Thread线程:中断异常InterruptedException、C3P0:java.lang.InterruptedException: sleep interrupted、com.intellij.openapi.application.RuntimeInterruptedException的实例源码、CountDownLatch InterruptedException的相关知识,请在本站搜索。
本文标签: