标签:是什么 内存溢出 except exec import term sch 为什么 public
package com.tgb.lk.thread; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadDemo { private Timer timer; private ExecutorService threadPool; private Thread thread1; private Thread thread2; private Thread thread3; public static void main(String[] args) { ThreadDemo threadDemo = new ThreadDemo(); threadDemo.init(); try { Thread.currentThread().join(); } catch (InterruptedException e) { } } public void init() { // 1.启动Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println(System.currentTimeMillis()); } }, 0, 3000); // 2.启动线程池 threadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { final int inner = i; threadPool.execute(new Runnable() { @Override public void run() { System.out.println(inner); } }); } // 3.线程挂起 thread1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000000000);// 假设时间设置的超长,看上去也相当于挂起了线程. } catch (InterruptedException e) { } } }); thread1.start(); // 4.线程挂起2 thread2 = new Thread(new Runnable() { @Override public void run() { try { Thread.currentThread().join(); Thread.currentThread().wait(); } catch (InterruptedException e) { } } }); thread2.start(); // 5.线程挂起3 thread3 = new Thread(new Runnable() { @Override public void run() { Thread.currentThread().suspend();// 挂起当前线程,可能会形成死锁哦,所以不建议使用suspend } }); thread3.start(); } }
运行后我们会发现main方法不能自己主动结束,原因当然是init方法中的一些线程堵塞了程序结束.怎样验证我的想法呢?
使用JConsole能够查看,假设你还没听过这个工具就有点out了,JDK5+都自带这个工具.
当我们凝视掉代码中main方法的Thread.currentThread().join();后再执行看Jconsole线程,结果例如以下:
原来Timer, 线程池, 线程操作中的sleep,wait,suspend等方法都能阻止我们的线程结束啊,找到原因了就找解决的方法吧,看以下代码:
package com.tgb.lk.thread; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadDemo { private Timer timer; private ExecutorService threadPool; private Thread thread1; private Thread thread2; private Thread thread3; public static void main(String[] args) { ThreadDemo threadDemo = new ThreadDemo(); threadDemo.init(); // try { // Thread.currentThread().join(); // } catch (InterruptedException e) { // } threadDemo.destory(); } public void init() { // 1.启动Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { System.out.println(System.currentTimeMillis()); } }, 0, 3000); // 2.启动线程池 threadPool = Executors.newFixedThreadPool(3); for (int i = 0; i < 10; i++) { final int inner = i; threadPool.execute(new Runnable() { @Override public void run() { System.out.println(inner); } }); } // 3.线程挂起 thread1 = new Thread(new Runnable() { @Override public void run() { try { Thread.sleep(1000000000);// 假设时间设置的超长,看上去也相当于挂起了线程. } catch (InterruptedException e) { } } }); thread1.start(); // 4.线程挂起2 thread2 = new Thread(new Runnable() { @Override public void run() { try { Thread.currentThread().join(); Thread.currentThread().wait(); } catch (InterruptedException e) { } } }); thread2.start(); // 5.线程挂起3 thread3 = new Thread(new Runnable() { @Override public void run() { Thread.currentThread().suspend();// 挂起当前线程,可能会形成死锁哦,所以不建议使用suspend } }); thread3.start(); } public void destory() { if (timer != null) { timer.cancel(); } if (threadPool != null) { threadPool.shutdown(); } if (thread1 != null) { thread1.interrupt(); } if (thread2 != null) { thread2.interrupt(); } if (thread3 != null) { thread3.stop(); } } }这段代码相比第一段代码我们在main中调用了destory这个方法.destory方法结束了timer,threadPool等对象的线程.执行一下代码,结果程序能够自己主动结束了,这时已经不再须要jconsole了.
拓展一下, 非常多程序都用spring来管理,假设在spring创建了线程,这些线程希望在spring结束时才去结束该怎么办呢?
import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class ClazzDaoImpl implements InitializingBean, DisposableBean { @Override public void afterPropertiesSet() throws Exception { //这里写初始化的方法 // init() } @Override public void destroy() throws Exception { //这里写结束线程的方法 // destory() } }
希望读者能从上面的过程中学到调试这样的问题的思路和方法,同一时候写代码时多多注意线程问题,自己的程序开启了对象尽量在自己的程序中同一时候写上结束对象的方法.
来个总结,非常多程序猿会用Timer,会用线程和线程池,但是非常少人关心这些对象的回收,假设这些线程不回收就会造成应用server结束不掉,有时还会造成内存溢出.有些人可能说我非常会写框架,但为什么流行度不广呢,由于咱们通常都考虑的太少,看看国外的优秀框架.是不是非常多类里面都有init和destory方法,这些框架大多数都考虑了对象的回收问题.作优秀的程序猿,从优秀的代码习惯開始吧~
标签:是什么 内存溢出 except exec import term sch 为什么 public
原文地址:http://www.cnblogs.com/cxchanpin/p/6752112.html