java线程之停止线程

     在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段原因是一样的。

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

 

   

      

				
时间: 2024-08-27 08:27:12

java线程之停止线程的相关文章

java多线程之停止线程

在多线程开发中停止线程是很重要的技术点.停止线程在Java语言中并不像break语句那样干脆,需要一些技巧性的处理. 一.  异常法 采用异常法来停止一个线程,首先我们需要了解一下两个方法的用法: 1.interrupt()方法 public class MyThread extends Thread{ @Override public void run() { for (int i = 1; i <= 10000; i++) { System.out.println("i="+

java多线程技术: interrupt() 中断线程, 优雅停止线程及原理

MyThread.class package cn.yilong.edcsapiservice.thread; public class MyThread extends Thread { @Override public void run() { System.out.println("开始睡觉"); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } System.out

Java中停止线程执行的方法

Java中停止线程执行的方法 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.暂停或停止线程的理论 在Java编程中,要暂停或停止当前正在运行的线程,有几种方法.对于把线程转入睡眠Sleep状态,使用Thread.sleep()是最正确的方式.或许有人会问,为什么不使用等待wait()或通知notify()?要知道,使用等待或通知都不是很好的方式. 线程可以使用等待wait()实现被阻塞,这属于条件等待的方式,当条件满足后,又会从阻塞转为等待状态

Java线程状态、线程停止、线程阻塞

线程状态(五种状态) Java 线程的生命周期包括创建,就绪,运行,阻塞,死亡5 个状态.一个 Java 线程总是处于这 5 个生命周期状态之一,并在一定条件下可以在不同状态之间进行转换 . 创建状态 (New Thread) 在 Java 语言中使用 new操作符创建一个线程后,该线程仅仅是一个空对象,它具备了线程的一些特征,但此时系统没有为其分配资源,这时的线程处于创建状态. 就绪状态 (Runnable) 使用 start()方法启动一个线程后,系统为该线程分配了除 CPU 外的所需资源,

java如何正确停止一个线程

Thread类中有start(), stop()方法,不过stop方法已经被废弃掉. 平时其实也有用过,共享一个变量,相当于标志,不断检查标志,判断是否退出线程 如果有阻塞,需要使用Thread的interrupt()方中断阻塞,线程开始检查标志(PS:抛出异常不会退出循环) ------------------------------------------------------------我是copy分割线------------------------------------------

Java线程池停止空闲线程是否有规则呢?

Java线程池中线程的数量超过核心线程的数量,且所有线程空闲,空闲时间超过keepAliveTime,会停止超过核心线程数量的线程,那么会保留哪些线程呢?是不是有规则呢? 测试代码: ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(5)); int taskNum = 13; for (int i = 0; i <

java多线程---停止线程

@Deprecated public final void stop() jdk源码中Thread的stop()方法已经被弃用了.那么怎么停止线程的呢? thread.interrupt();这就是需要用到的方法 一般建议使用抛异常的方法来实现停止线程.因为在catch块里可对异常信息进行相关处理. 如下: public class StopThread extends Thread{ /** * 停止一个线程可用Thread.stop(),但这个方法是不安全的,被弃用的.别用 * 还可以用Th

java笔记线程方式1线程终端与停止

public final void stop():让线程停止,过时了,但是还可以使用.public void interrupt():中断线程. 把线程的状态终止,并抛出一个InterruptedException. 1 public class ThreadStopDemo { 2 public static void main(String[] args) { 3 ThreadStop ts = new ThreadStop(); 4 ts.start(); 5 6 // 你超过三秒不醒过来

Java:多线程&lt;四&gt; Lock、停止线程、守护线程、join、优先级&amp;yield

Java1.5以后,Condition将Object监视器方法(wait, notify, notifyAll)分解成截然不同的对象,以便通过这些对象与任意Lock实现组合使用为每个对像提供多个等待set(wait-set).期中,Lock替代了synchronized方法和语句的使用,Condition替代了Objetc监视器方法和使用. 当线程处于冻结状态,就有可能线程就不会结束,interrupt用于清除线程的冻结状态.当没有指定的方式让冻结状态的线程恢复到运行状态时,这是需要对冻结状态进