精华内容
下载资源
问答
  • 有时开启一个线程是为了把耗时的操作转移到线程中执行,主进程中可以执行其它的任务,避免了因为大量的重复性操作导致主进程阻塞。 控制线程暂停的方法线程的同步用到了QMutex类,作为一个互斥锁控制进行保护。...

    需要线程停止的目的:

    有时开启一个线程是为了把耗时的操作转移到线程中执行,主进程中可以执行其它的任务,避免了因为大量的重复性操作导致主进程阻塞。

    控制线程暂停的方法:

    线程的同步用到了QMutex类,作为一个互斥锁控制进行保护。如果在主进程中把线程里面的互斥锁获取,那么线程中再次获取该锁就会失败,引起线程阻塞,主进程执行操作结束后,释放该锁,线程就会再次启动。以上思路实现了线程的暂停和开启。

    具体实现代码:

    1、线程中代码框架

    void thread::run(){
        mutex.lock();    //获得锁
        /*********/
        /........../
        mutex.unlock();  //释放锁
    }

    2、主进程中代码

    void mainwindows::doSomething(){
        thread.mutex.lock();
        /*****************/
        thread.mutex.unlock();
    }

    中途停止线程的方法

    Qt线程的停止可通过三种方式实现:

    1、利用quit(或者exit(0))

    this.quit();

    2、使用terminate

    this.terminate();

    this.wait();

    3、利用volatile

            一种是使用标志位,这种方法最好,在while循环中使用标志位判断是否满足进行循环的条件,并在run函数结束时将stoped置为初始化的值false。(stop定义:volatile bool stopped)

    第三中方法线程还在运行,只不过运行的内容是空的。

    测试第二中方法可以实现中途停止线程。

    展开全文
  • Java停止一个线程的几种方法

    千次阅读 2015-11-07 22:26:11
    Java中停止一个线程有三种方法,分别是stop,interrupt和设置标志位,我们依次来看一下这三种方法。 首先不推荐使用stop方法,原因有两点: 1、原则上只要一调用thread.stop()方法,线程就会立即停止,并抛出...

    Java中停止一个线程有三种方法,分别是stop,interrupt和设置标志位,我们依次来看一下这三种方法。

    首先不推荐使用stop方法,原因有两点:

    1、原则上只要一调用thread.stop()方法,线程就会立即停止,并抛出ThreadDeath error,查看了Thread的源代码后发现,原先Thread.stop0()方法是同步的,而如果我们工作线程的run()方法也是同步,那么这样会导致主线程和工作线程共同争用同一个锁(工作线程对象本身),由于工作线程在启动后就先获得了锁,所以无论如何,当主线程在调用t.stop()时,它必须要等到工作线程的run()方法执行结束后才能进行,结果会使及时性收到影响。

    2、thread.stop()是不安全的。它的不安全主要是针对于在停止该线程时会释放该线程所持有的所有的锁。一般任何进行加锁的代码块,都是为了保护数据的一致性,如果在调用thread.stop()后导致了该线程所持有的所有锁的突然释放,那么被保护数据就有可能呈现不一致性,其他线程在使用这些被破坏的数据时,有可能导致一些很奇怪的应用程序错误。

    我们来看interrupt的方法

    首先贴一段代码:

    class MyThread04 extends Thread {  
         
       public MyThread04(String threadName) {  
           super(threadName);  
       }  
    
       @Override 
       public void run() {  
             try{
            	 for (int j = 0; j<100; j++) {  
                     if(this.isInterrupted()) throw new InterruptedException();
                     System.out.println(Thread.currentThread().getName()+":"+j);
                     Thread.sleep(10000);
            	 }
            	 
             }catch (InterruptedException e) {  
    //             e.printStackTrace();  
             }  
           
              
           }  
             
    }

    或者是像下面这样写,try.catch块的范围较小,更利于调优

    class MyThread04 extends Thread {
    	public MyThread04(String threadName) {
    		super(threadName);
    	}
    
    	@Override
    	public void run() {
    		// try{
    		for (int j = 0; j < 100; j++) {
    			if (this.isInterrupted())
    				break;
    			System.out.println(Thread.currentThread().getName() + ":" + j);
    			try {
    				Thread.sleep(10000);
    			} catch (InterruptedException e) {
    				// TODO Auto-generated catch block
    				this.interrupt();// 由于处于sleep状态的线程被终止后会将标志位复位,所以需要重设一次
    				e.printStackTrace();
    			}
    		}
    	}
    }


    这里之所以抛出异常并捕获是考虑到对一个处于wait或者sleep状态的线程使用interrupt是会抛出异常的,所以需要事先捕获,主进程代码如下:

    MyThread04 t=new MyThread04("A");
    		t.start();
    		try {
    			Thread.sleep(5000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		t.interrupt();
    }

    使用interrupt()方法优雅的结束了进程。

    我们最后看看设置标志位的方法,代码如下:

    class MyThread04 extends Thread {
    
    	private boolean stop = false;
    
    	public MyThread04(String threadName) {
    		super(threadName);
    	}
    
    	@Override
    	public void run() {
    
    		for (int j = 0; j < 100; j++) {
    			if (this.stop == false) {
    				System.out.println(Thread.currentThread().getName() + ":" + j);
    				try {
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			} else {
    				break;
    			}
    
    		}
    
    	}
    
    	public void setStop() {
    		this.stop = true;
    	}
    }

    只要在主进程中调用setStop()方法就可以了,但此时如果for循环之后仍有代码,那么这些代码还是会被执行,为了避免这一点,我们可以采用抛出异常的方式处理,代码如下:

    class MyThread04 extends Thread {
    
    	private boolean stop = false;
    
    	public MyThread04(String threadName) {
    		super(threadName);
    	}
    
    	@Override
    	public void run() {
    
    		try{
    			for (int j = 0; j < 100; j++) {
    				if (this.stop == false) {
    					System.out.println(Thread.currentThread().getName() + ":" + j);
    					try {
    						Thread.sleep(1000);
    					} catch (InterruptedException e) {
    						e.printStackTrace();
    					}
    				} else {
    					throw new InterruptedException();
    				}
    
    			}
    			
    		}catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		
    
    	}
    
    	public void setStop() {
    		this.stop = true;
    	}
    }




    展开全文
  • 停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。在java中有以下3种方法可以终止正在运行的线程:使用退出标志,使...

    详见:http://www.cnblogs.com/greta/p/5624839.html

    停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。

    在java中有以下3种方法可以终止正在运行的线程:

    使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。

    使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。

    使用interrupt方法中断线程。

    1. 停止不了的线程

    interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。

    public class MyThread extends Thread {

    public void run(){

    super.run();

    for(int i=0; i<500000; i++){

    System.out.println("i="+(i+1));

    }

    }

    }

    public class Run {

    public static void main(String args[]){

    Thread thread = new MyThread();

    thread.start();

    try {

    Thread.sleep(2000);

    thread.interrupt();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    输出结果:

    ...

    i=499994

    i=499995

    i=499996

    i=499997

    i=499998

    i=499999

    i=500000

    2. 判断线程是否停止状态

    Thread.java类中提供了两种方法:

    this.interrupted(): 测试当前线程是否已经中断;

    this.isInterrupted(): 测试线程是否已经中断;

    那么这两个方法有什么图区别呢?

    我们先来看看this.interrupted()方法的解释:测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。

    public class MyThread extendsThread {public voidrun(){super.run();for(int i=0; i<500000; i++){

    i++;//System.out.println("i="+(i+1));

    }

    }

    }public classRun {public static voidmain(String args[]){

    Thread thread= newMyThread();

    thread.start();try{

    Thread.sleep(2000);

    thread.interrupt();

    System.out.println("stop 1??" +thread.interrupted());

    System.out.println("stop 2??" +thread.interrupted());

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    行结果:

    stop 1??false

    stop 2??false

    类Run.java中虽然是在thread对象上调用以下代码:thread.interrupt(), 后面又使用

    System.out.println("stop 1??" + thread.interrupted());

    System.out.println("stop 2??" + thread.interrupted());

    来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也证明了interrupted()方法的解释,测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以打印的结果是两个false.

    如何使main线程产生中断效果呢?

    public classRun2 {public static voidmain(String args[]){

    Thread.currentThread().interrupt();

    System.out.println("stop 1??" +Thread.interrupted());

    System.out.println("stop 2??" +Thread.interrupted());

    System.out.println("End");

    }

    }

    运行效果为:

    stop 1??true

    stop 2??false

    End

    方法interrupted()的确判断出当前线程是否是停止状态。但为什么第2个布尔值是false呢? 官方帮助文档中对interrupted方法的解释:

    测试当前线程是否已经中断。线程的中断状态由该方法清除。 换句话说,如果连续两次调用该方法,则第二次调用返回false。

    下面来看一下inInterrupted()方法。

    packagecom.my.test;public classTestThread {public static voidmain(String[] args) {

    Thread thread=Thread.currentThread();

    thread.interrupt();

    System.out.println("stop 1??" +thread.isInterrupted());

    System.out.println("stop 2??" +thread.isInterrupted());

    }

    }

    运行结果:

    stop 1??true

    stop 2??true

    isInterrupted()并未清除状态,所以打印了两个true。

    3. 能停止的线程--异常法

    有了前面学习过的知识点,就可以在线程中用for语句来判断一下线程是否是停止状态,如果是停止状态,则后面的代码不再运行即可:

    public class MyThread extendsThread {public voidrun(){super.run();for(int i=0; i<500000; i++){if(this.interrupted()) {

    System.out.println("线程已经终止, for循环不再执行");break;

    }

    System.out.println("i="+(i+1));

    }

    }

    }public classRun {public static voidmain(String args[]){

    Thread thread= newMyThread();

    thread.start();try{

    Thread.sleep(2000);

    thread.interrupt();

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    运行结果:

    ...

    i=202053i=202054i=202055i=202056

    线程已经终止, for循环不再执行

    上面的示例虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。看下面的例子:

    public class MyThread extendsThread {public voidrun(){super.run();for(int i=0; i<500000; i++){if(this.interrupted()) {

    System.out.println("线程已经终止, for循环不再执行");break;

    }

    System.out.println("i="+(i+1));

    }

    System.out.println("这是for循环外面的语句,也会被执行");

    }

    }

    使用Run.java执行的结果是:

    ...

    i=180136i=180137i=180138i=180139线程已经终止, for循环不再执行

    这是for循环外面的语句,也会被执行

    如何解决语句继续运行的问题呢? 看一下更新后的代码:

    public class MyThread extendsThread {public voidrun(){super.run();try{

    System.out.println("线程开始。。。");

    Thread.sleep(200000);

    System.out.println("线程结束。");

    }catch(InterruptedException e) {

    System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());

    e.printStackTrace();

    }

    }

    }

    使用Run.java运行的结果如下:

    ...

    i=203798

    i=203799

    i=203800

    线程已经终止, for循环不再执行

    进入MyThread.java类中的catch了。。。

    java.lang.InterruptedException

    at thread.MyThread.run(MyThread.java:13)

    4. 在沉睡中停止

    如果线程在sleep()状态下停止线程,会是什么效果呢?

    public class MyThread extendsThread {public voidrun(){super.run();try{

    System.out.println("线程开始。。。");

    Thread.sleep(200000);

    System.out.println("线程结束。");

    }catch(InterruptedException e) {

    System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());

    e.printStackTrace();

    }

    }

    }

    使用Run.java运行的结果是:

    线程开始。。。

    在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false

    java.lang.InterruptedException: sleep interrupted

    at java.lang.Thread.sleep(Native Method)

    at thread.MyThread.run(MyThread.java:12)

    从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。

    前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:

    public class MyThread extendsThread {public voidrun(){super.run();try{

    System.out.println("线程开始。。。");for(int i=0; i<10000; i++){

    System.out.println("i=" +i);

    }

    Thread.sleep(200000);

    System.out.println("线程结束。");

    }catch(InterruptedException e) {

    System.out.println("先停止,再遇到sleep,进入catch异常");

    e.printStackTrace();

    }

    }

    }public classRun {public static voidmain(String args[]){

    Thread thread= newMyThread();

    thread.start();

    thread.interrupt();

    }

    }

    运行结果:

    i=9998

    i=9999

    先停止,再遇到sleep,进入catch异常

    java.lang.InterruptedException: sleep interrupted

    at java.lang.Thread.sleep(Native Method)

    at thread.MyThread.run(MyThread.java:15)

    5. 能停止的线程---暴力停止

    使用stop()方法停止线程则是非常暴力的。.

    public class MyThread extendsThread {private int i = 0;public voidrun(){super.run();try{while (true){

    System.out.println("i=" +i);

    i++;

    Thread.sleep(200);

    }

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }

    }public classRun {public static void main(String args[]) throwsInterruptedException {

    Thread thread= newMyThread();

    thread.start();

    Thread.sleep(2000);

    thread.stop();

    }

    }

    运行结果:

    i=0

    i=1

    i=2

    i=3

    i=4

    i=5

    i=6

    i=7

    i=8

    i=9

    Process finished with exit code 0

    6.方法stop()与java.lang.ThreadDeath异常

    调用stop()方法时会抛出java.lang.ThreadDeath异常,但是通常情况下,此异常不需要显示地捕捉。

    public class MyThread extendsThread {private int i = 0;public voidrun(){super.run();try{this.stop();

    }catch(ThreadDeath e) {

    System.out.println("进入异常catch");

    e.printStackTrace();

    }

    }

    }public classRun {public static void main(String args[]) throwsInterruptedException {

    Thread thread= newMyThread();

    thread.start();

    }

    }

    stop()方法以及作废,因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。

    7. 释放锁的不良后果

    使用stop()释放锁将会给数据造成不一致性的结果。如果出现这样的情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误,一定要特别注意:

    public classSynchronizedObject {private String name = "a";private String password = "aa";public synchronized voidprintString(String name, String password){try{this.name =name;

    Thread.sleep(100000);this.password =password;

    }catch(InterruptedException e) {

    e.printStackTrace();

    }

    }publicString getName() {returnname;

    }public voidsetName(String name) {this.name =name;

    }publicString getPassword() {returnpassword;

    }public voidsetPassword(String password) {this.password =password;

    }

    }public class MyThread extendsThread {privateSynchronizedObject synchronizedObject;publicMyThread(SynchronizedObject synchronizedObject){this.synchronizedObject =synchronizedObject;

    }public voidrun(){

    synchronizedObject.printString("b", "bb");

    }

    }public classRun {public static void main(String args[]) throwsInterruptedException {

    SynchronizedObject synchronizedObject= newSynchronizedObject();

    Thread thread= newMyThread(synchronizedObject);

    thread.start();

    Thread.sleep(500);

    thread.stop();

    System.out.println(synchronizedObject.getName()+ " " +synchronizedObject.getPassword());

    }

    }

    输出结果:

    b aa

    由于stop()方法以及在JDK中被标明为“过期/作废”的方法,显然它在功能上具有缺陷,所以不建议在程序张使用stop()方法。

    8. 使用return停止线程

    将方法interrupt()与return结合使用也能实现停止线程的效果:

    public class MyThread extends Thread {

    public void run(){

    while (true){

    if(this.isInterrupted()){

    System.out.println("线程被停止了!");

    return;

    }

    System.out.println("Time: " + System.currentTimeMillis());

    }

    }

    }

    public class Run {

    public static void main(String args[]) throws InterruptedException {

    Thread thread = new MyThread();

    thread.start();

    Thread.sleep(2000);

    thread.interrupt();

    }

    }

    输出结果:

    ...

    Time: 1467072288503

    Time: 1467072288503

    Time: 1467072288503

    线程被停止了!

    不过还是建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止事件得以传播。

    展开全文
  • 停止一个线程

    2018-08-17 08:46:13
    如何正确地停止一个线程停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是...

    如何正确地停止一个线程?

    停止一个线程意味着在任务处理完任务之前停掉正在做的操作,也就是放弃当前的操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。
    在java中有以下3种方法可以终止正在运行的线程:

    1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
    2. 使用stop方法强行终止,但是不推荐这个方法,因为stop和suspend及resume一样都是过期作废的方法。
    3. 使用interrupt方法中断线程。
    4. 1. 停止不了的线程

      interrupt()方法的使用效果并不像for+break语句那样,马上就停止循环。调用interrupt方法是在当前线程中打了一个停止标志,并不是真的停止线程。

      public class MyThread extends Thread {
          public void run(){
              super.run();
              for(int i=0; i<500000; i++){
                  System.out.println("i="+(i+1));
              }
          }
      }
      
      public class Run {
          public static void main(String args[]){
              Thread thread = new MyThread();
              thread.start();
              try {
                  Thread.sleep(2000);
                  thread.interrupt();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      输出结果:

      ...
      i=499994
      i=499995
      i=499996
      i=499997
      i=499998
      i=499999
      i=500000

      2. 判断线程是否停止状态

      Thread.java类中提供了两种方法:

    5. this.interrupted(): 测试当前线程是否已经中断;
    6. this.isInterrupted(): 测试线程是否已经中断;
    7. 那么这两个方法有什么图区别呢?
      我们先来看看this.interrupted()方法的解释:测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。

      public class MyThread extends Thread {
          public void run(){
              super.run();
              for(int i=0; i<500000; i++){
                  i++;
      //            System.out.println("i="+(i+1));
              }
          }
      }
      
      public class Run {
          public static void main(String args[]){
              Thread thread = new MyThread();
              thread.start();
              try {
                  Thread.sleep(2000);
                  thread.interrupt();
      
                  System.out.println("stop 1??" + thread.interrupted());
                  System.out.println("stop 2??" + thread.interrupted());
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      运行结果:

      stop 1??false
      stop 2??false

      类Run.java中虽然是在thread对象上调用以下代码:thread.interrupt(), 后面又使用

      System.out.println("stop 1??" + thread.interrupted());
      System.out.println("stop 2??" + thread.interrupted());  

      来判断thread对象所代表的线程是否停止,但从控制台打印的结果来看,线程并未停止,这也证明了interrupted()方法的解释,测试当前线程是否已经中断。这个当前线程是main,它从未中断过,所以打印的结果是两个false.

      如何使main线程产生中断效果呢?

      public class Run2 {
          public static void main(String args[]){
              Thread.currentThread().interrupt();
              System.out.println("stop 1??" + Thread.interrupted());
              System.out.println("stop 2??" + Thread.interrupted());
      
              System.out.println("End");
          }
      }    

      运行效果为:

      stop 1??true
      stop 2??false
      End

      方法interrupted()的确判断出当前线程是否是停止状态。但为什么第2个布尔值是false呢? 官方帮助文档中对interrupted方法的解释:
      测试当前线程是否已经中断。线程的中断状态由该方法清除。 换句话说,如果连续两次调用该方法,则第二次调用返回false。

      下面来看一下inInterrupted()方法。

      public class Run3 {
          public static void main(String args[]){
              Thread thread = new MyThread();
              thread.start();
              thread.interrupt();
              System.out.println("stop 1??" + thread.isInterrupted());
              System.out.println("stop 2??" + thread.isInterrupted());
          }
      }

      运行结果:

      stop 1??true
      stop 2??true

      isInterrupted()并为清除状态,所以打印了两个true。

      3. 能停止的线程--异常法

      有了前面学习过的知识点,就可以在线程中用for语句来判断一下线程是否是停止状态,如果是停止状态,则后面的代码不再运行即可:

      public class MyThread extends Thread {
          public void run(){
              super.run();
              for(int i=0; i<500000; i++){
                  if(this.interrupted()) {
                      System.out.println("线程已经终止, for循环不再执行");
                      break;
                  }
                  System.out.println("i="+(i+1));
              }
          }
      }
      
      public class Run {
          public static void main(String args[]){
              Thread thread = new MyThread();
              thread.start();
              try {
                  Thread.sleep(2000);
                  thread.interrupt();
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }

      运行结果:

      ...
      i=202053
      i=202054
      i=202055
      i=202056
      线程已经终止, for循环不再执行

      上面的示例虽然停止了线程,但如果for语句下面还有语句,还是会继续运行的。看下面的例子:

      public class MyThread extends Thread {
          public void run(){
              super.run();
              for(int i=0; i<500000; i++){
                  if(this.interrupted()) {
                      System.out.println("线程已经终止, for循环不再执行");
                      break;
                  }
                  System.out.println("i="+(i+1));
              }
      
              System.out.println("这是for循环外面的语句,也会被执行");
          }
      }

      使用Run.java执行的结果是:

      ...
      i=180136
      i=180137
      i=180138
      i=180139
      线程已经终止, for循环不再执行
      这是for循环外面的语句,也会被执行

      如何解决语句继续运行的问题呢? 看一下更新后的代码:

      public class MyThread extends Thread {
          public void run(){
              super.run();
              try {
                  for(int i=0; i<500000; i++){
                      if(this.interrupted()) {
                          System.out.println("线程已经终止, for循环不再执行");
                              throw new InterruptedException();
                      }
                      System.out.println("i="+(i+1));
                  }
      
                  System.out.println("这是for循环外面的语句,也会被执行");
              } catch (InterruptedException e) {
                  System.out.println("进入MyThread.java类中的catch了。。。");
                  e.printStackTrace();
              }
          }
      }

      使用Run.java运行的结果如下:

      ...
      i=203798
      i=203799
      i=203800
      线程已经终止, for循环不再执行
      进入MyThread.java类中的catch了。。。
      java.lang.InterruptedException
          at thread.MyThread.run(MyThread.java:13)

      4. 在沉睡中停止

      如果线程在sleep()状态下停止线程,会是什么效果呢?

      public class MyThread extends Thread {
          public void run(){
              super.run();
      
              try {
                  System.out.println("线程开始。。。");
                  Thread.sleep(200000);
                  System.out.println("线程结束。");
              } catch (InterruptedException e) {
                  System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());
                  e.printStackTrace();
              }
      
          }
      }

      使用Run.java运行的结果是:

      线程开始。。。
      在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false
      java.lang.InterruptedException: sleep interrupted
          at java.lang.Thread.sleep(Native Method)
          at thread.MyThread.run(MyThread.java:12)

      从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。

      前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:

      public class MyThread extends Thread {
          public void run(){
              super.run();
              try {
                  System.out.println("线程开始。。。");
                  for(int i=0; i<10000; i++){
                      System.out.println("i=" + i);
                  }
                  Thread.sleep(200000);
                  System.out.println("线程结束。");
              } catch (InterruptedException e) {
                   System.out.println("先停止,再遇到sleep,进入catch异常");
                  e.printStackTrace();
              }
      
          }
      }
      
      public class Run {
          public static void main(String args[]){
              Thread thread = new MyThread();
              thread.start();
              thread.interrupt();
          }
      }

      运行结果:

      i=9998
      i=9999
      先停止,再遇到sleep,进入catch异常
      java.lang.InterruptedException: sleep interrupted
          at java.lang.Thread.sleep(Native Method)
          at thread.MyThread.run(MyThread.java:15)

      5. 能停止的线程---暴力停止

      使用stop()方法停止线程则是非常暴力的。

      public class MyThread extends Thread {
          private int i = 0;
          public void run(){
              super.run();
              try {
                  while (true){
                      System.out.println("i=" + i);
                      i++;
                      Thread.sleep(200);
                  }
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      }
      
      public class Run {
          public static void main(String args[]) throws InterruptedException {
              Thread thread = new MyThread();
              thread.start();
              Thread.sleep(2000);
              thread.stop();
          }
      }

      运行结果:

      i=0
      i=1
      i=2
      i=3
      i=4
      i=5
      i=6
      i=7
      i=8
      i=9
      
      Process finished with exit code 0

      6.方法stop()与java.lang.ThreadDeath异常

      调用stop()方法时会抛出java.lang.ThreadDeath异常,但是通常情况下,此异常不需要显示地捕捉。

      public class MyThread extends Thread {
          private int i = 0;
          public void run(){
              super.run();
              try {
                  this.stop();
              } catch (ThreadDeath e) {
                  System.out.println("进入异常catch");
                  e.printStackTrace();
              }
          }
      }
      
      public class Run {
          public static void main(String args[]) throws InterruptedException {
              Thread thread = new MyThread();
              thread.start();
          }
      }

      stop()方法以及作废,因为如果强制让线程停止有可能使一些清理性的工作得不到完成。另外一个情况就是对锁定的对象进行了解锁,导致数据得不到同步的处理,出现数据不一致的问题。

      7. 释放锁的不良后果

      使用stop()释放锁将会给数据造成不一致性的结果。如果出现这样的情况,程序处理的数据就有可能遭到破坏,最终导致程序执行的流程错误,一定要特别注意:

      public class SynchronizedObject {
          private String name = "a";
          private String password = "aa";
      
          public synchronized void printString(String name, String password){
              try {
                  this.name = name;
                  Thread.sleep(100000);
                  this.password = password;
              } catch (InterruptedException e) {
                  e.printStackTrace();
              }
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public String getPassword() {
              return password;
          }
      
          public void setPassword(String password) {
              this.password = password;
          }
      }
      
      public class MyThread extends Thread {
          private SynchronizedObject synchronizedObject;
          public MyThread(SynchronizedObject synchronizedObject){
              this.synchronizedObject = synchronizedObject;
          }
      
          public void run(){
              synchronizedObject.printString("b", "bb");
          }
      }
      
      public class Run {
          public static void main(String args[]) throws InterruptedException {
              SynchronizedObject synchronizedObject = new SynchronizedObject();
              Thread thread = new MyThread(synchronizedObject);
              thread.start();
              Thread.sleep(500);
              thread.stop();
              System.out.println(synchronizedObject.getName() + "  " + synchronizedObject.getPassword());
          }
      }

      输出结果:

      b  aa

      由于stop()方法以及在JDK中被标明为“过期/作废”的方法,显然它在功能上具有缺陷,所以不建议在程序张使用stop()方法。

      8. 使用return停止线程

      将方法interrupt()与return结合使用也能实现停止线程的效果:

      public class MyThread extends Thread {
          public void run(){
              while (true){
                  if(this.isInterrupted()){
                      System.out.println("线程被停止了!");
                      return;
                  }
                  System.out.println("Time: " + System.currentTimeMillis());
              }
          }
      }
      
      public class Run {
          public static void main(String args[]) throws InterruptedException {
              Thread thread = new MyThread();
              thread.start();
              Thread.sleep(2000);
              thread.interrupt();
          }
      }

      输出结果:

      ...
      Time: 1467072288503
      Time: 1467072288503
      Time: 1467072288503
      线程被停止了!

      不过还是建议使用“抛异常”的方法来实现线程的停止,因为在catch块中还可以将异常向上抛,使线程停止事件得以传播。

    展开全文
  • 2、使用stop方法强行终止,但是不推荐这方法,因为stop和suspend及resume一样都是过期作废的方法。 3、使用interrupt方法中断线程。 class MyThread extends Thread { volatile boolean stop = false; public ...
  • 1. 什么是停止线程停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。2. 错误方式 - 调用Thread.stop()方法虽然停止一个线程可以用Thread.stop()方法,但最好不要用它。它确实可以...
  • 1.中断方法停止线程: package thread_stop.way; public class MyThread extends Thread { public void run() { try{ for (int i = 0; i ; i++) { if (this.interrupted()) { System.out....
  • 如何停止一个线程

    2019-03-19 19:43:26
    停止一个线程的最佳方法是让它执行完毕,没有办法立即停止一个线程,但你可以控制何时或什么条件下让他执行完毕。 通过条件变量控制线程的执行,线程内部检查变量状态,外部改变变量值可控制停止执行。为保证线程间...
  • 停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是这个方法是不安全,而且是...
  • 停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是这个方法是不安全,而且是...
  • 原因是stop方法是通过抛出一个ThreadDeathError来让线程直接停止的,如果是在同步代码块中,它会释放锁。 stop方法停止线程就像按开关键来关机一样,它是没有进行一些善后处理。 下面就通过一个例子来演示...
  • 停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是这个方法是不安全,而且是...
  • 停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。在java中有以下3种方法可以终止正在运行的线程:使用退出标志,使...
  • 之前本人写了篇防止Controller中的线程被重复调用文章,大概代码如下: //sonarqube检查要求static变量必须是final,为避开检查,使用final HashMap public final static HashMap<String,Thread> ...
  • 要点 线程的用法 线程的stop方法 线程stop过程中存在的问题 interrupt中断的用法 ...为何不能简单地停止一个线程?【为何废弃stop()】 协作的任务执行模式【正确停止线程的思路】 interrupt的原生支持 ...
  • 停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行的线程,但是这个方法是不安全的,而且是已被废弃的方法。在java中有以下3种方法可以终止正在运行的线程:使用退出标志,使...
  • 复习多线程的知识,偶然看到一道题:如何正确的停止一个线程?我第一反应是使用stop()方法停止,操作以后发现stop已经被废弃了。 经过查找资料,发现是使用interrupt()进行中断标记然后在进行停止,特此写这篇随笔...
  • 1 如何停止一个线程? 答: 1.1 这道题想考察什么? 答:(1)考察要点 ●是否对线程的用法有了解;是否对线程的stop方法有了解(初级) ●是否对线程stop过程中存在的问题有认识;是否熟悉interrupt中断的用法(中级) ●...
  • 原标题:Java如何正确地停止一个线程如何正确地停止一个线程停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实...
  • 下面将依次介绍: 1. 线程状态 2. start方法源码 3.什么是线程池?...7. 如何停止一个线程(含代码) 8.如何合理配置Java 线程池?如 CPU 密集型任务,基本线程池 应该配置多大?IO 密集型...
  • 、前言之前本人写了篇防止Controller中的线程被重复调用文章,大概代码如下://sonarqube检查要求static变量必须是final,为避开检查,使用final HashMappublic final static HashMap threadMap = new HashMap...
  • 如何正确地停止一个线程停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是这...
  • 如何正确地停止一个线程停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是...
  • java中如何停止一个线程

    千次阅读 2018-10-11 16:01:33
    JDK1.0本来有一些像stop(),suspend()和resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中被他们弃用了,之后java API的设计者就没有提供一个兼容且线程安全的方法停止一个线程。当run()...
  • 如何停止一个线程

    2019-09-21 20:38:35
    既然我们没法去关闭一个线程,那我们就可以软实现去关闭一个线程,比如中断,还有就是设置状态,不满足条件时就不执行run方法。 下面是我看一篇比较好文章。感谢作者辛勤付出。 https://www.cnb...
  • 如何正确停止一个线程? 想要启动线程需要调用 Thread 类 start() 方法,并在 run() 方法中定义需要执行任务,那么如何正确停止它? 为什么需要正确停止一个线程 一般情况下,我们不会手动停止一个线程,而是...
  • 停止一个线程意味着在任务处理完任务之前停掉正在做操作,也就是放弃当前操作。停止一个线程可以用Thread.stop()方法,但最好不要用它。虽然它确实可以停止一个正在运行线程,但是...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,897
精华内容 1,158
关键字:

停止一个线程的方法