码迷,mamicode.com
首页 > 编程语言 > 详细

java线程之停止线程

时间:2016-06-27 13:59:07      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:

     在Java中有以下3种方法可以终止一个正在运行的线程:
     1、使用退出标志,是线程正常退出,也就是run方法完成后线程终止。
     2、使用stop方法强制终止线程,蛋不推荐使用这个方法,因为stop、suspend和resume一样,都是作废过期的方法。
     3、使用interrupt方法中断线程,大多数停止一个线程使用Thread.interrupt()方法,但是这个方法不会终止一个正在运行的线程,还需要加入一些判断才可以完成线程的停止。
下面我就用几个例子来介绍一下各种停止线程的效果。
一、停不了的线程——interrupt
本例子将调用interrupt()方法来停止线程,但是效果并不理想,并不能停止正在运行的线程,因为调用interrupt()方法仅仅是在当前线程中打了一个停止的标记,并不能真的停止线程。
	public static void main(String[] args) {
MyThread1 t = new MyThread1(); t.start(); try { Thread.sleep(2);
Thread.interrupted(); } catch (InterruptedException e) { System.out.println("main catch"); e.printStackTrace(); } } public static class MyThread1 extends Thread { @Override public void run() {
super.run(); for (int i = 0; i < 5000; i++) { System.out.println("i=" + (i + 1)); } } }

     运行结果我值截取了最后一段,控制台上正好输出到5000,说明调用interrupt方法并没有停止线程,运行结果如下:

              技术分享
           那么怎么才能停止线程呢?下面我回来介绍。

二、能停止的线程——异常法
      先看一个例子:
	public static void main(String[] args) throws InterruptedException {

		MyThread t = new MyThread();
		t.start();
		Thread.sleep(50);
		t.interrupt();
		System.out.println("end");
	}

	public static class MyThread extends Thread {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			for (int i = 0; i < 5000; i++) {
				if (this.interrupted()) {
					System.out.println("已经是停止状态了!我要退出了!");
					break;
				}

				System.out.println("i=" + (i + 1));
			}
			System.out.println("如果我被输出了,说明run方法还在继续执行,线程并未停止!");

		}
	}

       输出结果如下:

           技术分享

          从上面的结果可以看出来,这样写只是把for循环结束了,但是下面接着输出了“如果我被输出了,说明run方法还在继续执行,线程并未停止!”这句话,说明这样写并不能让run方法停止,所以这样写不可行。下面再来看一个例子。
	public static void main(String[] args) throws InterruptedException {

		MyThread t = new MyThread();
		t.start();
		Thread.sleep(50);
		t.interrupt();
		System.out.println("end");
	}

	public static class MyThread extends Thread {

		@Override
		public void run() {
			super.run();
			try {
				for (int i = 0; i < 5000; i++) {
					if (this.interrupted()) {
						System.out.println("已经是停止状态了!我要退出了!");
//异常法结束线程 throw new InterruptedException(); } System.out.println("i=" + (i + 1)); } System.out.println("我在for下面"); } catch (InterruptedException e) { System.out.println("进入Thread线程的run方法中的catch!"); e.printStackTrace(); } } }

      下面来看一下控制台上的输出结果:

          技术分享

         来分析一下结果,throw new InterruptedException()这句话下面的内容已经不会再执行了,因为“我在for下面”这句话并没有输出来,而是进入了catch,结束了整个run方法。所以异常方法来停止线程方法是靠谱的。
三、在沉睡中停止线程
        public static void main(String[] args) {

		try {
			MyThread t = new MyThread();
			t.start();
			Thread.sleep(200);
			t.interrupt();
		} catch (Exception e) {
			System.out.println("main catch");
			e.printStackTrace();
		}
		System.out.println("end!");

	}

	public static class MyThread extends Thread {

		@Override
		public void run() {

			super.run();
			try {
				System.out.println("run begin");
//为了确保能停止线程,这个休眠时间尽量长一点,如果时间太短,有可能主线程还没休眠结束呢,子线程就休眠结束了,这个线程也就正常运行了。 sleep(2000); System.out.println("run end"); } catch (Exception e) { System.out.println("在沉睡中被停止!进去catch!" + this.isInterrupted()); e.printStackTrace(); } } }

 

      运行结果如下:

           技术分享

          来分析一下结果,"run end"这句话没有输出,说明子线程里的sleep下面的内容再也不会执行了,而是进入到catch里面了,从而停止了run方法。说明这样写也是靠谱的。

四、能停止的线程——暴力停止

  使用stop()方法停止线程是非常暴力的行为,并且使用stop()方法会导致运行结果不一样,已经被官方文档废弃使用了。下面我来展示一个例子。

 

	public static void main(String[] args) {

		MyThread t = new MyThread();
		t.start();
		try {
Thread.sleep(9000); t.stop(); } catch (Exception e) { e.printStackTrace(); } } public static class MyThread extends Thread { private int i = 0; @Override public void run() { super.run(); while (true) { i++; System.out.println("i=" + i); try { sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }

 

五、使用return停止线程
     将interrupt()和return结合也能实现停止线程的效果。但是建议使用抛异常停止线程,因为可以处理发生异常时候的相关信息。下面看一段代码。
       public static void main(String[] args) throws InterruptedException {

		MyThread t = new MyThread();
		t.start();
		Thread.sleep(2);
		t.interrupt();

	}

	public static class MyThread extends Thread {

		@Override
		public void run() {

			super.run();

			for (int i = 0; i < 5000; i++) {
				if (this.interrupted()) {
					System.out.println("已经是停止状态了!我要退出了!");
					return;
				}
				System.out.println("i=" + (i + 1));
			}

		}
	}

      下面看一下运行结果:

           技术分享

六、暂停线程
      暂停线程异味着此线程还可以恢复运行,在java中使用suspend()方法暂停线程,使用resume()方法恢复线程。下面看一段代码。
	public static void main(String[] args) throws InterruptedException {

		MyThread t = new MyThread();
		t.start();
		//A段    暂停线程
		t.suspend();
		System.out.println("A="+System.currentTimeMillis() +"\t"+"i="+t.getI());
		Thread.sleep(500);
		System.out.println("A="+System.currentTimeMillis() +"\t"+"i="+t.getI());
		//B段    继续恢复
		t.resume();
		System.out.println("B="+System.currentTimeMillis() +"\t"+"i="+t.getI());
		Thread.sleep(500);
		System.out.println("B="+System.currentTimeMillis() +"\t"+"i="+t.getI());
		//C段    暂停线程
		t.suspend();
		System.out.println("C="+System.currentTimeMillis() +"\t"+"i="+t.getI());
		Thread.sleep(500);
		System.out.println("C="+System.currentTimeMillis() + "\t"+"i="+t.getI());
	}

	public static class MyThread extends Thread {

		private long i = 0;
		public long getI(){
			return i;
		}
		public void setI(long i){
			this.i=i;
		}
		@Override
		public void run() {
		
			super.run();
			while (true) {
				i++;
			}
		}
	}
  下面来分析一下运行结果:在A段中,先执行的是suspend()暂停线程的方法,所以从结果可以看出,系统的当前时间在变,但是i值确一直是0,说明线程没有在执行,仍是初始化的值,到了B段,执行了resume()恢复线程的方法,从结果也可以看出,当前系统的时间在变,i值也在改变,说面线程已经被恢复并在执行了,到了C段,出现这样的结果和A段原因是一样的。

      技术分享

以上我说了很多小例子,如果亲手敲一遍代码,看一下执行结果,会有更好的理解,毕竟线程执行的结果不是单一的。

 

 

   

 

 

    

 

      




java线程之停止线程

标签:

原文地址:http://www.cnblogs.com/chentong/p/5614965.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!