java 一个线程会不会因为java实现界面跳转转而停止

抓取占用CPU高的JAVA线程,进而找出有问题的WEB页面 | 张戈博客
博客宗旨 把最实用的经验,分享给最需要的读者,希望每一位来访的朋友都能有所收获!
<span class="tipso_style" id="tip-w" data-tipso=''>
浏览 6659168
留言 16442
随便挑了些,看你喜欢嘛
关于博客 张戈博客是关注互联网以及分享IT运维工作经验的个人博客,主要涵盖了操作系统运维、实用脚本编程以及博客网站建设等经验教程。我的博客宗旨:把最实用的经验,分享给最需要的读者,希望每一位来访的朋友都能有所收获!17015人阅读
Java(40)
为什么不能使用Thread.stop()方法?
从SUN的官方文档可以得知,调用Thread.stop()方法是不安全的,这是因为当调用Thread.stop()方法时,会发生下面两件事:
1. 即刻抛出ThreadDeath异常,在线程的run()方法内,任何一点都有可能抛出ThreadDeath Error,包括在catch或finally语句中。
2. 释放该线程所持有的所有的锁
当线程抛出ThreadDeath异常时,会导致该线程的run()方法突然返回来达到停止该线程的目的。ThreadDetath异常可以在该线程run()方法的任意一个执行点抛出。但是,线程的stop()方法一经调用线程的run()方法就会即刻返回吗?
Java代码 &
public&static&void&main(String[]&args)&{ &&&&&&&&&&try&{ &&&&&&&&&&&&&&Thread&t&=&new&Thread()&{ &&&&&&&&&&&&&&&&&&public&synchronized&void&run()&{ &&&&&&&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&&&&&&long&start=System.currentTimeMillis(); &&&&&&&&&&&&&&&&&&&&&&&&&&for&(int&i&=&0;&i&&&<span style="color:#c0;&i&#43;&#43;)
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&runing..&&&#43;&i); &&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println((System.currentTimeMillis()-start)/<span style="color:#c0); &&&&&&&&&&&&&&&&&&&&&&}&catch&(Throwable&ex)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&Caught&in&run:&&&&#43;&ex); &&&&&&&&&&&&&&&&&&&&&&&&&&ex.printStackTrace(); &&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&}; &&&&&&&&&&&&&&t.start(); &&&&&&&&&&&&&&&&&&&&&&&&&&&&Thread.sleep(<span style="color:#c0); &&&&&&&&&&&&&&t.stop();&&&&&&&&&&&}&catch&(Throwable&t)&{ &&&&&&&&&&&&&&System.out.println(&Caught&in&main:&&&&#43;&t); &&&&&&&&&&&&&&t.printStackTrace(); &&&&&&&&&&} &&&&&&&&}&&
public static void main(String[] args) {
Thread t = new Thread() {
public synchronized void run() {
long start=System.currentTimeMillis();
for (int i = 0; i & 100000; i++)
System.out.println(&runing..& + i);
System.out.println((System.currentTimeMillis()-start)/1000);
} catch (Throwable ex) {
System.out.println(&Caught in run: & + ex);
ex.printStackTrace();
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println(&Caught in main: & + t);
t.printStackTrace();
假设我们有如上一个工作线程,它的工作是数数,从1到1000000,我们的目标是在它进行数数的过程中,停止该线程的运作。如果我们按照上面的方式来调用thread.stop()方法,原则上是可以实现我们的目标的,根据SUN官方文档的解释,加上在上面的程序中,主线程只休眠了100ms,而工作线程从1数到1000000所花时间大概是4-5s,那么该工作线程应该只从1数到某个&#20540;(小于1000000),然后线程停止。&
但是根据运行结果来看,并非如此。
runing..99998
runing..99999
runing..99998
runing..99999
每次运行的结果都表明,工作线程并没有停止,而是每次都成功的数完数,然后正常中止,而不是由stop()方法进行终止的。这个是为什么呢?根据SUN的文档,原则上只要一调用thread.stop()方法,那么线程就会立即停止,并抛出ThreadDeath error,查看了Thread的源代码后才发现,原先Thread.stop0()方法是同步的,而我们工作线程的run()方法也是同步,那么这样会导致主线程和工作线程共同争用同一个锁(工作线程对象本身),由于工作线程在启动后就先获得了锁,所以无论如何,当主线程在调用t.stop()时,它必须要等到工作线程的run()方法执行结束后才能进行,结果导致了上述奇怪的现象。
把上述工作线程的run()方法的同步去掉,再进行执行,结果就如上述第一点描述的那样了
可能的结果:
runing..4149
runing..4150
runing..4151
runing..4152runing..4152Caught in run: java.lang.ThreadDeath
runing..5245
runing..5246
runing..5247
runing..5248runing..5248Caught in run: java.lang.ThreadDeath
接下来是看看当调用thread.stop()时,被停止的线程会不会释放其所持有的锁,看如下代码:
Java代码 &
public&static&void&main(String[]&args)&{ &&&&&&&&&&final&Object&lock&=&new&Object(); &&&&&&&&&&try&{ &&&&&&&&&&&&&&Thread&t0&=&new&Thread()&{ &&&&&&&&&&&&&&&&&&public&void&run()&{ &&&&&&&&&&&&&&&&&&&&&&try&{ &&&&&&&&&&&&&&&&&&&&&&&&&&synchronized&(lock)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&thread-&&&&#43;&getName() &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#43;&&&acquire&lock.&); &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&sleep(<span style="color:#c0);&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&thread-&&&&#43;&getName() &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#43;&&&release&lock.&); &&&&&&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&&&&&}&catch&(Throwable&ex)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&Caught&in&run:&&&&#43;&ex); &&&&&&&&&&&&&&&&&&&&&&&&&&ex.printStackTrace(); &&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&}; &&&&&&&&&&&&&&&&Thread&t1&=&new&Thread()&{ &&&&&&&&&&&&&&&&&&public&void&run()&{ &&&&&&&&&&&&&&&&&&&&&&synchronized&(lock)&{ &&&&&&&&&&&&&&&&&&&&&&&&&&System.out.println(&thread-&&&&#43;&getName() &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&#43;&&&acquire&lock.&); &&&&&&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&&&&&} &&&&&&&&&&&&&&}; &&&&&&&&&&&&&&&&t0.start(); &&&&&&&&&&&&&&&&&&&&&&&&&&&&Thread.sleep(<span style="color:#c0); &&&&&&&&&&&&&&&&&&&&&&&&&&&&t1.start(); &&&&&&&&&&}&catch&(Throwable&t)&{ &&&&&&&&&&&&&&System.out.println(&Caught&in&main:&&&&#43;&t); &&&&&&&&&&&&&&t.printStackTrace(); &&&&&&&&&&} &&&&&&&&}&&
public static void main(String[] args) {
final Object lock = new Object();
Thread t0 = new Thread() {
public void run() {
synchronized (lock) {
System.out.println(&thread-&& + getName()
+ & acquire lock.&);
sleep(3000);// sleep for 3s
System.out.println(&thread-&& + getName()
+ & release lock.&);
} catch (Throwable ex) {
System.out.println(&Caught in run: & + ex);
ex.printStackTrace();
Thread t1 = new Thread() {
public void run() {
synchronized (lock) {
System.out.println(&thread-&& + getName()
+ & acquire lock.&);
t0.start();
// Give t time to get going...
Thread.sleep(100);
//t0.stop();
t1.start();
} catch (Throwable t) {
System.out.println(&Caught in main: & + t);
t.printStackTrace();
当没有进行t0.stop()方法的调用时, 可以发现,两个线程争用锁的顺序是固定的。
thread-&Thread-0 acquire lock.
thread-&Thread-0 release lock.
thread-&Thread-1 acquire lock.
但调用了t0.stop()方法后,(去掉上面的注释//t0.stop();),可以发现,t0线程抛出了ThreadDeath error并且t0线程释放了它所占有的锁。
thread-&Thread-0 acquire lock.
thread-&Thread-1 acquire lock.
Caught in run: java.lang.ThreadDeath
java.lang.ThreadDeath
&at java.lang.Thread.stop(Thread.java:715)
&at com.yezi.test.timeout.ThreadStopTest.main(ThreadStopTest.java:40)
从上面的程序验证结果来看,thread.stop()确实是不安全的。它的不安全主要是针对于第二点:释放该线程所持有的所有的锁。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。
如何正确停止线程
关于如何正确停止线程,给出了一个很好的答案, 总结起来就下面3点(在停止线程时):
1. 使用violate boolean变量来标识线程是否停止
2. 停止线程时,需要调用停止线程的interrupt()方法,因为线程有可能在wait()或sleep(), 提高停止线程的即时性
3. 对于blocking IO的处理,尽量使用InterruptibleChannel来代替blocking IO
核心如下:
If you are writing your own small thread then you should follow the following example code.
private volatile Thread myT
public void stopMyThread() {
Thread tmpThread = myT
myThread =
if (tmpThread != null) {
tmpThread.interrupt();
public void run() {
if (myThread == null) {
// stopped before started.
// all the run() method's code goes here
// do some work
Thread.yield(); // let another thread have some time perhaps to stop this one.
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException(&Stopped by ifInterruptedStop()&);
// do some more work
} catch (Throwable t) {
// log/handle all errors here
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:2429843次
积分:19464
积分:19464
排名:第391名
原创:364篇
转载:67篇
评论:308条
文章:18篇
阅读:29659
阅读:23460
(7)(2)(1)(1)(2)(7)(4)(1)(1)(2)(3)(1)(1)(1)(6)(4)(5)(4)(9)(10)(15)(3)(3)(4)(7)(11)(19)(5)(3)(3)(25)(15)(21)(4)(5)(11)(1)(8)(3)(3)(4)(7)(7)(1)(5)(6)(11)(7)(7)(4)(1)(3)(2)(2)(2)(2)(2)(1)(4)(14)(2)(20)(10)(13)(4)(7)(8)(8)(41)(1)(10)你正在使用的浏览器版本过低,将不能正常浏览和使用知乎。显示一个java跳转页面_Java教程_动态网站制作指南
显示一个java跳转页面
来源:人气:11858
原文地址链接
高级的/应用的启动时间会很长,假如你让一个漂亮的跳转页面显示在程序上,通常会增加用户的好感。然而,这样的效果可能会超出你的想象。
&&&&&& 假如你尝试在主线程里简单的显示一个跳转页面,你可能会碰到问题,你会注重到当你的程序启动并顺序执行时,跳转页面会一闪而过。或许,它可能根本不会出现!这是可能的,只要你的代码与下面类似:
&&& public void startApp() {&&&&&& myDisplay.setCurrent(mySplashScreen);&&&&&& doAllSlowInitializations();&&&&&& myDisplay.setCurrent(myGameScreen);&&& }
&&&&&& 这个问题的原因是因为应用程序治理器不答应在startApp()方法执行过程中看见任何Screen或Canvas。可以参考MIDP Javadoc的javax.microedition.lcdui包获取更多信息。
&&&&&& 技巧就是应该把显示跳转页面和游戏的初始化用不同的线程来处理,就像下面的代码例子那样。这将使startApp()方法很快就能执行完,并且跳转页面能尽可能显示更长的时间。两个线程可以使用共享变量来实现同步,在初始化完成时,跳转页面应该消失。
&&& public void startApp() {&&&&&&& Thread splashScreenTest = new Thread(new SplashScreenTest.SplashScreen());&&&&&&& splashScreenTest.start();&&&&&&& &&&&&&&& Thread myGameThread = new Thread(this);&&&&&&&& myGameThread.start();& &&& }
&&&&&& 下面的例子程序就是使用这样的技术来显示一个跳转页面的。
&&&&&& 另外,大多数常规技术是使用晚装载来减少启动时间,它的意思是当要使用对象和资源时才初始化它们。这种方法能很好的减少你的程序对内存的需求,但是程序也有出错的危险,应当仔细考虑。
下载程序源代码
优质网站模板

我要回帖

更多关于 java swing界面跳转 的文章

 

随机推荐