精华内容
下载资源
问答
  • 多线程有中断吗
    千次阅读
    2022-01-22 19:00:41

            对于线程的停止,通常情况下我们是不会去手动去停止的,而是等待线程自然运行至结束,但在实际开发中,很多情况中需要我们提前去手动来停止线程,比如程序中出现异常错误、使用者关闭程序等情况中。如果不能很好地停止线程那么可能会导致各种问题,所以正确的停止线程是非常的重要的,常见的中断线程的方式有以下几种:

    1、方式一:使用 Thread 类的 stop() 方法来终止线程:

            Thread 类的 stop() 方法虽然可以终止线程,但该方法已被标识为废弃方法,原因是 stop() 方法太过暴力,即使线程只执行一半,也会被强行终止,不能保证线程资源正确释放,线程不安全,从而产生不可预料的结果,因此不提倡使用。

    2、方式二:根据 volatile 修饰的标志位判断线程是否需要中断:

        public static class ChangeObjectThread extends Thread 
        {
    		// 表示是否停止线程
    		private volatile boolean stopMe = true;
    		public void stopMe() {
    			stopMe = false;
    		}
     
    		@Override
    		public void run() {
    			while (!stopMe) {
                    System.out.println("I'm running");
    			}
    		}
    	}

            在上面的代码里面,定义了一个标记变量 stopMe,用于标识线程是否需要退出,当 stopMe() 方法被调用时,stopMe 就会被赋值为 false,此时在代码里面的 while(!stopMe) 就会检测到这个改动,线程就退出了

    3、方式三:通过 interrupt 中断机制终止线程:

            该方式的核心就是通过 interrupt() 方法设置线程的中断标志位,并通过 isInterrupt()/interrupted() 方法监视并判断中断信号,当线程检测到为 true 时则说明接收到中断信号,此时需要被中断线程做相应的处理。但如何去响应这个中断信号,被中断线程有完全的自主权,也就是中断结果是死亡或是继续运行,取决于这个被中断线程本身的逻辑。

    • Thread.interrupte():设置线程的中断标志位为 true,表示被其他线程进行了中断操作,但它不会像 stop() 方法那样强制中断正在运行的线程,仅仅起到通知被停止线程的作用;而被中断线程,则需要通过监视自身的标志位是否被中断来进行响应,比如使用 isInterrupted() 或 interrupted() 方法来判断是否被中断;
    • this.interrupted():测试当前线程是否已经中断。如果连续两次调用该方法,第一次返回 true,第二次返回false,因为 interrupted() 方法具有清除状态的功能,它内部实现是调用的当前线程的 isInterrupted(),并且会重置当前线程的中断状态。
    • this.isInterrupted():测试线程是否已经中断,但是不会清除状态标识

            前面说过,interrupt 机制需要被中断线程去监视中断标志位是否发生变化并做处理,那么当线程处于阻塞状态,确切来说,线程被 Object.wait()、Thread.join() 和 Thread.sleep() 三种方法之一阻塞时,应该如何处理呢?其实 interrupte() 方法也是支持线程阻塞情况的,一旦在上面几种情况下,线程的中断状态被置为“中断”,就会抛出中断异常 InterruptedException,从而提早地终结被阻塞状态,所以我们只需要捕获 InterruptedException 异常并对中断进行响应即可。不过在抛出 InterruptedException 之前,JVM 会先将该线程的中断标志位复位,所以此时调用 isInterrupted() 方法将会返回 false,但如果线程既没有被阻塞,又没有通过 isInterrupted()/isInterrupted() 进行监视并做出相应的处理,此时调用 interrupt() 将不起作用。下面我们就针对两种 interrupt() 机制写两个例子:

    3.1、使用 interrupt() + isInterrupted() 来中断线程:

     public static void main(String[] args)
        {
            //创建 interrupt-1 线程
            Thread thread = new Thread(() -> {
                while (true) {
                    System.out.println(Thread.currentThread().getName() + "线程正在执行...");
                    if (Thread.currentThread().isInterrupted())
                    {
                        System.out.println("线程1 接收到中断信息,中断线程...中断标记:" + Thread.currentThread().isInterrupted());
                        Thread.currentThread().interrupted(); 
                        System.out.println("经过 Thread.interrupted() 复位后,中断标记:" + Thread.currentThread().isInterrupted());
                        break;
                    }
                }
            }, "interrupt-1");
            //启动线程 1
            thread.start();
    
            //创建 interrupt-2 线程,用于设置线程1的中断状态
            new Thread(() -> {
                try {
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                System.out.println("设置线程中断...." );
                thread.interrupt();
    
            },"interrupt-2").start();
        }

    3.2、使用 interrupt() + InterruptedException 来中断线程:

        public static void main(String[] args)
        {
            //创建 interrupt-1 线程
            Thread thread = new Thread(() -> {
                while (true) {
                    System.out.println(Thread.currentThread().getName() + "线程1开始执行...");
                    //判断当前线程是否中断,
                    if (Thread.currentThread().isInterrupted())
                    {
                        System.out.println("线程1 接收到中断信息,中断线程...中断标记:" + Thread.currentThread().isInterrupted());
                        break;
                    }
    
                    try {
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        //因为抛出InterruptedException异常后,会导致中断标志复位为false,所以再次设置线程的中断状态,也可以直接使用break中断线程
                        Thread.currentThread().interrupt();
                        //break;
                    }
                }
                System.out.println("线程1执行结果...");
            }, "interrupt-1");
            //启动线程 1
            thread.start();
    
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            System.out.println("设置线程中断...." );
            //用于设置线程1的中断状态
            thread.interrupt();
        }

            从上面的执行结果可以证明,当线程处于阻塞状态时,也是可以感受到中断通知并抛出异常的,所以不用担心长时间休眠中线程感受不到中断了。

            对于线程的停止,最正确最优雅的方式就是通过 interrupt() 的方式来实现,但 interrupt() 仅起到通知被停止线程的作用,对被停止的线程而言,它拥有完全的自主权,既可以立即停止,也可以选择一段时间后停止,也可以选择不停止。比如抛出 InterruptedException 后,再次中断设置,让程序能后续继续进行终止操作;也比如线程在进行 IO 操作时,比如写文件操作,这时接收到终止线程的信号,那么它不会立马停止,而是根据自身业务来判断该如何处理,是将整个文件写入成功后再停止还是不停止都取决于被通知线程的处理,因为如果立马终止线程就可能造成数据的不完整性,这并不是业务所不希望的结果。那么可能很多读者会疑惑,既然这样那存在的意义有什么呢,其实是因为对于 Java 而言,就是期望程序之间是能够相互通知、协作的管理线程

    参考文章:

    https://www.cnblogs.com/myseries/p/10918819.html

    https://www.cnblogs.com/i-code/p/13804624.html

    更多相关内容
  • interrupt字面上是中断的意思,但在Java里Thread.interrupt()方法实际上通过某种方式通知线程,并不会直接中止该线程
  • C++11关于thead的应用,利用std::condition std::mutex提供如何中断,停止和继续功能,
  • 主要介绍了java多线程中断代码详解,具有一定参考价值,需要的朋友可以了解下。
  • 主要介绍了Java多线程中断机制三种方法及示例,向大家分享了这三种方法的介绍几代码示例,具有一定参考价值,需要的朋友可以了解下。
  • 在Java中start和tun方法可用被用来启动线程,而用interrupt方法来中断或终止线程,以下我们就来详解Java多线程编程中线程的启动、中断或终止操作
  • 多线程中断机制

    万次阅读 多人点赞 2017-08-18 12:02:55
    在 java中启动线程非常容易,大多数情况下是让一个线程执行完自己的任务然后自己停掉... 在当前的api中,Thread.suspend、Thread.stop等方法都被Deprecated了,线程只能用interrupt中断,而且不是立刻中断,只是发了一

    友情推荐:

    1. 线程池原理
    2. 深入Thread.sleep
    3. head first Thread.join()

    在 java中启动线程非常容易,大多数情况下是让一个线程执行完自己的任务然后自己停掉。一个线程在未正常结束之前, 被强制终止是很危险的事情. 因为它可能带来完全预料不到的严重后果,比如会带着自己所持有的锁而永远的休眠,迟迟不归还锁等。在当前的api中,Thread.suspend、Thread.stop等方法都被Deprecated了,线程只能用interrupt中断,而且不是立刻中断,只是发了一个类似于信号量的东西,通过修改了被调用线程的中断状态来告知那个线程, 说它被中断了,至于什么时候中断,这个有系统判断,会在一个合适的时候进行中断处理。

    /**
     * Created by Zero on 2017/8/17.
     */
    public class ThreadTest1 {
        public static void main(String[] args) {
            NThread nThread = new NThread();
            System.out.println("interrupt执行前");
            nThread.start();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            nThread.interrupt();
            System.out.println("interrupt执行后");
        }
    
        /**
         * 测试多线程的中断机制
         */
        static class NThread extends Thread{
            @Override
            public void run() {
                super.run();
                while(true){
                    System.out.println("依然存活...");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    这里写图片描述

    在上面代码中,线程睡醒之后,调用thread线程的interrupt方法,catch到InteruptedException,设置标志位。interrupt()方法相当于线程睡着的时候一盆凉水来吵醒它,线程表示不开心,并向你抛出一个大大的异常以示不满。

    这里写图片描述

    • 首先:线程中断是一种协作机制,调用线程对象的interrupt方法并不一定就中断了正在运行的线程,它只是要求线程自己在合适的时间中断自己。
    • 其次:任务的方法必须是可中断的,即方法必须抛出InterruptedException。

    由此可见,interrupt() 方法并不能立即中断线程,该方法仅仅告诉线程外部已经有中断请求,至于是否中断还取决于线程自己。在Thread类中除了interrupt() 方法还有另外两个非常相似的方法:interrupted 和 isInterrupted 方法,下面来对这几个方法进行说明:

    • interrupt 此方法是实例方法,用于告诉此线程外部有中断请求,并且将线程中的中断标记设置为true,而不是立即中断。
    • interrupted 此方法是类方法,用来判断当前线程是否已经中断。线程的中断状态由该方法清除。
    • isInterrupted 此方法是实例方法,用来判断线程是否已经中断。线程的中断状态不受该方法的影响。

    总结:java线程中断机制通过调用Thread.interrupt() 方法来做的,这个方法通过修改了被调用线程的中断状态来告知那个线程说它被中断了。对于非阻塞中的线程,只是改变了中断状态,即Thread.isInterrupted() 将返回true;对于可取消的阻塞状态中的线程,比如等待在这些函数上的线程,Thread.sleep()、Object.wait()、Thread.join(), 这个线程收到中断信号后,会抛出InterruptedException,同时会把中断状态置回为true。但调用Thread.interrupted()会对中断状态进行复位。

    /**
     * Created by Zero on 2017/8/17.
     */
    public class ThreadTest1 {
        public static void main(String[] args) {
            NThread nThread = new NThread();
            nThread.start();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("cancel执行前" + System.currentTimeMillis());
            nThread.cancel();
        }
    
        /**
         * 测试多线程的中断机制
         */
        static class NThread extends Thread {
    
            private boolean isCancel;
    
            @Override
            public void run() {
                while (!isCancel) {
                    System.out.println("依然存活...");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        Thread.currentThread().interrupt();
                    }
                }
                System.out.println("while结束" + System.currentTimeMillis());
            }
    
            public void cancel() {
                this.isCancel = true;
            }
        }
    }

    执行结果:

    依然存活...
    cancel执行前1502964413042
    while结束1502964415042

    机智的你,此刻一定发现执行前后相差2000毫秒,难道cancel()方法执行了2000毫秒?这纯属扯淡,里面没有任何耗时操作,就是一个赋值而已,其实是子线程的退出,前提条件是while循环结束,当且仅当cancel标示设置为true的瞬间立马执行while的判断,此时的时间差才可以忽略不计(1毫秒内),但是当我们调用cancel方法将isCancel 标记设置为true 时,while循环里面有一个耗时操作(休眠5000毫秒),只有等待耗时操作执行完毕后才会去检查这个标记,所以cancel方法和线程退出中间有时间间隔。

    接下来,我们通过interrupt 和 isinterrupt 方法来中断线程,代码如下:

    /**
     * Created by Zero on 2017/8/17.
     */
    public class ThreadTest1 {
        public static void main(String[] args) {
            NThread nThread = new NThread();
            nThread.start();
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("interrupt执行前"+System.currentTimeMillis());
            nThread.interrupt();
        }
    
        /**
         * 测试多线程的中断机制
         */
        static class NThread extends Thread{
    
            @Override
            public void run() {
                while(!interrupted()){
                    System.out.println("依然存活...");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        System.out.println("InterruptedException");
                        Thread.currentThread().interrupt();
                    }
                }
                System.out.println("interrupt执行后"+System.currentTimeMillis());
            }
        }
    }
    
    依然存活...
    interrupt执行前1502965915683
    InterruptedException
    interrupt执行后1502965915683

    这次立马中断了,是因为在开启子线程后,经过执行3000毫秒的休眠,线程执行了interrupt 方法,此时子线程的5000毫秒休眠还没结束,就像上述所说的睡眠中被一盆冷水吵醒,很不开心的抛了异常,Thread.currentThread().interrupt() 改变了线程的标记状态,在抛出InterruptedException 的同时,线程的中断标志被清除了,再次执行while循环语句的时候,!interrupted() 此时是false,便不再执行while语句。

    此处如果去掉Thread.currentThread().interrupt() ,线程便会无休止的执行下去,此处就不上代码了,就注释掉这一行,运行就可以看到效果,经常看到一些代码在catch中不作任何处理,其实有时候这样是很危险的,此处已经证明。

    两点建议:
    1. 除非你知道线程的中断策略,否则不应该中断它。
    2. 任务代码不该猜测中断对执行线程的含义。遇到InterruptedException异常时,不应该将其捕获后“吞掉”,而应该继续向上层代码抛出。

    微信扫我,^_^

    展开全文
  • 多线程——2如何正确的中断线程

    千次阅读 2019-11-02 10:28:33
    多线程探险——2常用方法 一、内容安排 什么是守护线程(Daemon Thread) Join方法的含义 自己join自己会是什么效果 Interrupt方法 综合案列:如何去停止线程 二、文章内容 1. 什么...

    多线程探险——2如何正确的中断java线程

    一、内容安排

    1. 什么是守护线程(Daemon Thread)
    2. Join方法的含义
    3. 自己join自己会是什么效果
    4. Interrupt方法
    5. 综合案列:如何去停止线程

    二、文章内容

    为了能中断线程我们首先需要了解线程中的几个方法, 最后在案列中实现如何正确的停止一个线程; 如果对这几个方法非常熟悉可跳过前面内容直接看综合案列

    1. 什么是守护线程(Daemon Thread)

    • 守护线程:从字面意思我们可以感觉到好像是要守护某个事物一样, 实际上简单理解守护线程就是另外一个线程的兄弟(真的做到了不求同年同月同日生,但求同年同月同日死的那种兄弟), 到代码中就是主线程生命周期结束守护线程申明周期跟着结束。

    • 应用场景:心跳检测的场景, 当主线程和另外一台服务器保持长连接的通信时需要定时检测心跳,那么假如主线程停止了心跳检测线程同样应该结束申明周期

    • 代码实现

      • 目标:此处模拟主线程(mian线程)工作10秒, 守护线程是死循环不停的工作
      • 效果:十秒之后主线程生命周期结束,守护线程也随之停止工作
    • 具体代码

      public class DaemonThreadDemo {
      
          public static void main(String[] args) throws InterruptedException {
              //1.创建一个守护线程
              Thread daemonThread = new Thread(() -> {
                  while (true) {
                      System.out.println("daemon thread is working...");
                      try {
                          TimeUnit.SECONDS.sleep(1);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              });
      
              //2.设置daemonThread作为mian的守护线程
              daemonThread.setDaemon(true);
              //3.启动守护线程
              daemonThread.start();
              //4.模拟主线程工作10秒
              TimeUnit.SECONDS.sleep(10);
          }
      }
      
    • 思考: 如果我不设置daemonThread为面的守护线程他会不会随着main的结束而结束

    2.Join方法的含义

    • join:join方法字面意思就是加入, 通俗的理解join方法就是多个线程是一个饭点组合队伍, 有个兄弟A在洗头他喊了你一声等我一下我马上洗完了一起去,这时候你就只能等着他了; 在代码中如果A线程join到B线程那么B线程就会一直等着A线程执行结束后才会执行join后面的代码

    • 应用场景

      • 一个主线程开了三个线程去执行任务, 当三个线程执行完成任务后主线程才能继续执行后续代码
    • 案列步骤

      • 实现在主线程(你自己)中开启一个兄弟线程A
      • 在A中实现洗头十分钟
      • 在主线程中启动A线程, 然后调用A的join方法
      • 在join之后打印兄弟你终于整完了
    • 案列实现

      public class JoinDemo {
          public static void main(String[] args) throws InterruptedException {
              //1.A兄弟线程
              Thread A = new Thread(() -> {
                  for (int i = 0; i < 10; i++) {
                      System.out.println("A兄弟在洗头中");
                      try {
                          TimeUnit.SECONDS.sleep(1);
                      } catch (InterruptedException e) {
                          e.printStackTrace();
                      }
                  }
              });
              //2.A兄弟开始洗头
              A.start();
              //3.A兄弟叫Mian兄弟等她
              A.join();
              //4.A洗完头了
              System.out.println("兄弟你终于洗完头了, 走吧去哪里吃饭!!!");
          }
      }
      

    3.自己join自己会是什么效果

    • 情景: 假如你当前线程调用了join方法这会有什么效果, 也就是说自己等自己,实际上这是一个死循环程序一直也不会结束;

    • 如何获取当前线程

      Thread yourself = Thread.currentThread();
      
    • 具体代码

      public class JoinYourself {
          public static void main(String[] args) throws InterruptedException {
              Thread yourself = Thread.currentThread();
              yourself.join();
          }
      }
      
    • 最终效果

      • 程序一直不会结束,处于阻塞状态
      • 线程快照如下:
      "main" #1 prio=5 os_prio=0 tid=0x0000000002b13800 nid=0x40f8 in Object.wait() [0x0000000000dcf000]
         java.lang.Thread.State: WAITING (on object monitor)
      	at java.lang.Object.wait(Native Method)
      	- waiting on <0x000000076b105ca0> (a java.lang.Thread)
      	at java.lang.Thread.join(Thread.java:1249)
      	- locked <0x000000076b105ca0> (a java.lang.Thread)
      	at java.lang.Thread.join(Thread.java:1323)
      	at com.huangguoyu.JoinYourself.main(JoinYourself.java:6)
      

    4.Interrupt方法

    • Interrupt方法:

      • 该方法可以改变线程是否被中断的一个状态值,但是他不会真正的中断线程; 可以通过isInterrupted方法获取这个状态值的改变
      • 调用该方法后如果线程整处于join、sleep、wait状态那么线程会捕获到InterruptedException异常
    • 尝试使用Interrupt中断线程

      • 实际效果是不能终止线程, 程序会一直处于运行状态
      public class InterruptedMethod {
          public static void main(String[] args) {
              Thread thread = new Thread(() -> {
                  while (true) {
      
                  }
              });
              thread.start();
              thread.interrupt();
              System.out.println(thread.isInterrupted());
          }
      }
      
    • 测试线程在sleep状态能不能捕获到InterruptedException异常

      public class InterruptedMethod {
          public static void main(String[] args) {
              Thread thread = new Thread(() -> {
                  try {
                      TimeUnit.SECONDS.sleep(100);
                  } catch (InterruptedException e) {
                      System.out.println("捕获到了异常!!!");
                      e.printStackTrace();
                  }
              });
              thread.start();
              thread.interrupt();
              System.out.println(thread.isInterrupted());
          }
      }
      

    5.如何停止线程

    1. 线程的stop方法, 此方法被标记了将被抛弃,此处不再详细介绍
    2. 可以使用状态量flag来停止线程(这里实现方式涉及到java内存模型后续更新)
    3. 首先停止线程我们可以设置线程为某个线程的守护线程只要主线程申明周期结束了守护线程也随之结束了; 那么问题来了我们怎么来控制主线程,实际上我们可以让主线程处于wait、join、sleep状态我们就可以调用主线程的中断方法来结束主线程;那么挖掘机又来了, 主线程执行完守护先成就结束,假如这时候守护线程任务还没有执行完怎么, 好的大家可能想到了join可以让主线程等某个兄弟
    • 案列

      ​ 实现一个线程去执行任务,并且在这个线程中提供中断任务的方法,也就是提供停止执行任务的方法

      • 自定义线程类,并提供execute方法用于执行任务
      • 在run方法中开启一个任务线程去执行任务
      • 在自定义线程类中提供shutdown方法去停止当前线程
      • 测试
    • 案列实现

      
      public class MyIterruptedableThread extends Thread{
      
          //需要执行的任务
          private Runnable runnable;
      
          public MyIterruptedableThread(Runnable target) {
              this.runnable = target;
          }
      
          @Override
          public void run() {
              //开启执行任务线程
              Thread task = new Thread(runnable);
              //设置task线程为当前线程的守护线程
              task.setDaemon(true);
              task.start();
              //让当前线程等待task线程执行结束
              try {
                  task.join();
              } catch (InterruptedException e) {
                  //接收到中断异常当前线程执行结束, 其守护线程task也随之结束
                  e.printStackTrace();
              }
          }
      
          /**
           * 中断当前线程
           */
          public void shutDown() {
              this.interrupt();
          }
      
          /**
           * 测试
           */
          public static void main(String[] args) throws InterruptedException {
              //定义任务
              Runnable task = ()->{
                while (true) {
                    System.out.println("task is processing...");
                }
              };
              //创建主线,控制任务生命周期
              MyIterruptedableThread myIterruptedableThread = new MyIterruptedableThread(task);
              //启动线程执行任务
              myIterruptedableThread.start();
              //执行5秒后中断任务
              TimeUnit.SECONDS.sleep(5);
              System.out.println("任务执行五秒, 结束任务");
              myIterruptedableThread.shutDown();
      
          }
      }
      
      
    展开全文
  • 线程中断的几种方式

    千次阅读 2021-08-10 14:51:47
    三种方法可以使终止线程。 1. 使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。 2. 使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)...

    有三种方法可以使终止线程。

    1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止。
    
    2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend、resume一样,也可能发生不可预料的结果)。
    
    3.  使用interrupt方法中断线程。
    
    • 1.使用退出标识终止线程
      当run方法执行完后,线程就会退出。但有时run方法是永远不会结束的。如在服务端程序中使用线程进行监听客户端请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。如果想让循环永远运行下去,可以使用while(true){……}来处理。但要想使while循环在某一特定条件下退出,最直接的方法就是设一个boolean类型的标志,并通过设置这个标志为true或false来控制while循环是否退出。下面给出了一个利用退出标志终止线程的例子。
    package chapter2;
     
    public class ThreadFlag extends Thread
    {
        public volatile boolean exit = false;
     
        public void run()
        {
            while (!exit);
        }
        public static void main(String[] args) throws Exception
        {
            ThreadFlag thread = new ThreadFlag();
            thread.start();
            sleep(5000); // 主线程延迟5秒
            thread.exit = true;  // 终止线程thread
            thread.join();
            System.out.println("线程退出!");
        }
    }
    

    在上面代码中定义了一个退出标志exit,当exit为true时,while循环退出,exit的默认值为false.在定义exit时,使用了一个Java关键字volatile,这个关键字的目的是使exit同步,也就是说在同一时刻只能由一个线程来修改exit的值

      1. 使用stop方法终止线程

      使用stop方法可以强行终止正在运行或挂起的线程。我们可以使用如下的代码来终止线程:

       thread.stop();
    

    虽然使用上面的代码可以终止线程,但使用stop方法是很危险的,就象突然关闭计算机电源,而不是按正常程序关机一样,可能会产生不可预料的结果,因此,并不推荐使用stop方法来终止线程。

      1. 使用interrupt方法终止线程
    使用interrupt方法来终端线程可分为两种情况:
    
    (1)线程处于阻塞状态,如使用了sleep方法。
    
    (2)使用while(!isInterrupted()){……}来判断线程是否被中断。
    

    在第一种情况下使用interrupt方法,sleep方法将抛出一个InterruptedException例外,而在第二种情况下线程将直接退出。下面的代码演示了在第一种情况下使用interrupt方法。

    package chapter2;
     
    public class ThreadInterrupt extends Thread
    {
        public void run()
        {
            try
            {
                sleep(50000);  // 延迟50秒
            }
            catch (InterruptedException e)
            {
                System.out.println(e.getMessage());
            }
        }
        public static void main(String[] args) throws Exception
        {
            Thread thread = new ThreadInterrupt();
            thread.start();
            System.out.println("在50秒之内按任意键中断线程!");
            System.in.read();
            thread.interrupt();
            thread.join();
            System.out.println("线程已经退出!");
        }
    }
    

    上面代码的运行结果如下:

    50秒之内按任意键中断线程!
     
        sleep interrupted
        线程已经退出! 
    

    在调用interrupt方法后, sleep方法抛出异常,然后输出错误信息:sleep interrupted.

    注意:在Thread类中有两个方法可以判断线程是否通过interrupt方法被终止。一个是静态的方法interrupted(),一个是非静态的方法isInterrupted(),这两个方法的区别是interrupted用来判断当前线是否被中断,而isInterrupted可以用来判断其他线程是否被中断。因此,while (!isInterrupted())也可以换成while (!Thread.interrupted())。

    展开全文
  • java 多线程-02-线程中断 interrupt()

    万次阅读 2021-06-11 09:34:03
    线程中断 interrupt() 线程的Thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,完全取决于目标线程的自行决定。线程会...
  • 这篇文章主要记录使用 interrupt() 方法中断线程,以及如何对InterruptedException进行处理。感觉对InterruptedException异常进行处理是一件谨慎且技巧的活儿。 由于使用stop()方法停止线程非常的暴力,人家线程...
  • 多线程机制,你懂得。。多多多多多下载,谢谢支持,办板报的了,歇息一下
  • 多线程】c语言中的多线程

    千次阅读 2022-04-24 17:18:12
    多线程就是多个线程同时并发执行。 1. 为什么用多线程? 1). 避免拥塞 单个线程中的程序,是按照顺序执行的,排在前面的程序如果发生异常卡住(阻塞),会影响到后面的程序执行。多线程就等于是异步调用,避免这个...
  • Java:线程的三种中断方式

    千次阅读 2021-05-27 10:40:16
    文章目录前言一、线程的Stop()操作二、线程的Interrupt()方法进行中断操作1.stop()方法的缺点2.Interrupt()方法三、使用run标志位进行判断总结 前言 在 Java 中,并发机制非常重要,但并...而在多线程当中
  • Java多线程 interrupt中断阻塞

    千次阅读 2019-02-20 13:29:36
    ——interrupt()方法并不是中断线程,而是中断阻塞状态,或者将线程的[中断标志位]置为true。 ——对于未阻塞的线程,interrupt()只是造成[中断标志位]=true,线程本身运行状态不受影响。 ——对于阻塞的线程,...
  • 万字图解Java多线程

    万次阅读 多人点赞 2020-09-06 14:45:07
    java多线程我个人觉得是javaSe中最难的一部分,我以前也是感觉学会了,但是真正有多线程的需求却不知道怎么下手,实际上还是对多线程这块知识了解不深刻,不知道多线程api的应用场景,不知道多线程的运行流程等等,...
  • 今天开始就来总结一下java多线程的基础知识点,下面是本篇的主要内容(大部分知识点参考java核心技术卷1): 1.什么是线程以及多线程与进程的区别 2.多线程的创建与启动 3.中断线程和守护线程以及线程优先级 4....
  • java多线程中断(interrupt)问题

    千次阅读 2017-07-21 09:23:08
    摘要在java中,想要让一个线程停下来,三种办法: (1)采用退出标志,使得run方法执行完之后线程自然终止。 (2)使用stop强行终止线程,但该方法由于安全问题已经被deprecated。 (3)使用中断机制。
  • 线程中断详解

    万次阅读 多人点赞 2018-07-05 19:01:44
    中断线程线程的thread.interrupt()方法是中断线程,将会设置该线程中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取决于这个程序本身。线程会不时地检测这个中断标示...
  • 用于线程中断,该方法并不能直接中断线程,只会将线程的中断标志位改为true。它只会给线程发送一个中断状态,线程是否中断取决于线程内部对该中断信号做什么响应,若不处理该中断信号,线程就不会中断。 简而言之,...
  • 只有启动才有中断的,我觉得这个线程的启动很必要讲解的。 线程的启动 我们知道启动线程,也就是调用 start()方法去启动一个线程,当 run 方法中的代码执行完毕 以后,线程的生命周期也将终止。调用 start 方法...
  • 如下的代码, 演示了线程在sleep的过程中, 被中断的情况. 子线程每隔一秒打印当前的时间, 循环10次, 会执行10s. 主线程在其第六秒的时候, 让子线程休眠. 此时子线程抛出被中断的异常. import java.util.Da
  • 线程中断到底是什么

    千次阅读 2020-03-27 09:28:41
    我们如何让线程安全的停止呢? 1. 线程自然终止 自然执行完或抛出未处理异常。 2. stop(),resume(),suspend()方法 ...停止多线程: public void stop(); 销毁多线程: public void destory(); 挂起...
  • C++ Boost 多线程(三),线程的中断

    千次阅读 2018-05-27 10:35:11
    //线程中断 int main() { boost::thread t1(func1, 11); t1.interrupt(); boost::thread t2(func2, 22); t2.interrupt(); boost::thread t3(func3, 33); t3.interrupt(); t1.join(); t2.join(); t3.join()...
  • 多线程IO阻塞中断

    千次阅读 2016-10-18 16:22:38
    关于Java多线程IO阻塞如何中断的问题,基于一个基本条件,关闭任务发生阻塞的底层资源问题,可以中断多线程任务。对于IO阻塞问题,给出了两个示例,一个是Socket IO,关闭掉Socket IO之后确实可以中断;另一种是...
  • 说来惭愧这个问题找了挺久,作为一个并发编程渣渣,甚至都不知道怎么用idea进行多线程调试,这次虽然找问题找了半天,但也算有点收获 场景是我要开一个线程去定期用各种参数请求一个接口,来缓存这个接口的结果,...
  • 在我们的程序中经常会一些不达到目的不会退出的线程,例如:我们一个下载程序线程,该线程在没有下载成功之前是不会退出的,若此时用户觉得下载速度慢,不想下载了,这时就需要用到我们的线程中断机制了,告诉...
  • 多线程与原子类问题,遇到了线程中断,记录一下 多线程和原子类多看看源码 Executors.newFixedThreadPool底层调用了ThreadPoolExecutor的方法,所以使用ThreadPoolExecutor对象 AtomicInteger保证了内存可见性和原子...
  • Go学习笔记—多线程

    千次阅读 2021-12-01 10:27:19
    多线程编程 ​ 一个进程可以包含多个线程,这些线程运行的一定是同一个程序(进程==程序),且都由当前进程中已经存在的线程通过系统调用的方式创建出来。进程是资源分配的基本单位,线程是调度运行的基本单位,线程...
  • 最近在系统回顾多线程这一部分的内容,对线程中断方式这一部分相比之前了不同的认识。整理一下,如理解偏颇之处,还请各位大神不惜赐教。 在看高洪岩《Java多线程编程核心技术》的时候里面讲了很多种停止线程...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 292,044
精华内容 116,817
关键字:

多线程有中断吗

友情链接: FDIV10E.zip