关于java线程中stop interrupt daemon wait notify

小编 2026-06-04 阅读:1525 评论:0
一。关于终止线程stop与interrupt  一般来说,线程执行结束后就变成消亡状态,乍看之下...

一。关于终止线程stop与interrupt

  一般来说,线程执行结束后就变成消亡状态,乍看之下我们并不需要人为进行干预(人为停止线程),不过凡事都有例外吧,在服务器或者其他应用场景下,线程为了提供服务而一直在不停的运转,因此必要时刻我们还需“人为干涉的”。

  通常情况下,终止线程有两种方式:stop与interrupt

  1) stop:暴力的停止线程(不管线程执行到哪段代码,立刻干掉),这个方法因为过于暴力会导致安全问题,因此JDK不推荐使用。

  2) interrupt:优雅停止,调用该方法会通知线程可以进行停止操作了,此时线程只是变成可停止状态(thread.isInterrupted的值为true),实际上并没有停止

  请看下段代码:

  

关于java线程中stop interrupt daemon wait notify关于java线程中stop interrupt daemon wait notify
 1 package com.bdqn.lyrk.basic; 2  3 /** 4  * 一个线程设置共享变量的值,保持ID与name值相同 5  * 另外一个线程读取共享变量的值,发现ID与name值不同时打印 6  * 7  * @author chen.nie 8  * @date 2018/1/30 9  **/10 public class StopThreadUnsafe {11 12     public static User user = new User();13 14     public static class User {15         private int id;16         private String name;17 18         public int getId() {19             return id;20         }21 22         public void setId(int id) {23             this.id = id;24         }25 26         public String getName() {27             return name;28         }29 30         public void setName(String name) {31             this.name = name;32         }33 34         public User() {35             id = 0;36             name = "0";37         }38 39         @Override40         public String toString() {41             return "User [id=" + id + ",name=" + name + "]";42         }43     }44 45     public static class ChangeObjectThread extends Thread {46 47         @Override48         public void run() {49             while (true) {50                 synchronized (user) {51                     if (Thread.currentThread().isInterrupted()) {52                         break;53                     }54                     int i = (int) System.currentTimeMillis() / 1000;55                     user.setId(i);56                     try {57                         Thread.sleep(100);58                     } catch (InterruptedException e) {59                         Thread.currentThread().interrupt();60                     }61                     user.setName("" + i);62 63                 }64                 Thread.yield();65             }66         }67     }68 69     public static class ReadObjectThread extends Thread {70 71         @Override72         public void run() {73             while (true) {74                 synchronized (user) {75                     if (user.getId() != Integer.parseInt(user.getName())) {76                         System.out.println(user);77                     }78                 }79                 Thread.yield();80             }81         }82     }83 }
View Code

 

  Main方法:

关于java线程中stop interrupt daemon wait notify关于java线程中stop interrupt daemon wait notify
 1 package com.bdqn.lyrk.basic; 2  3 public class Main { 4     public static void main(String[] args) throws InterruptedException { 5         new StopThreadUnsafe.ReadObjectThread().start(); 6         while (true) { 7             StopThreadUnsafe.ChangeObjectThread thread = new StopThreadUnsafe.ChangeObjectThread(); 8             thread.start(); 9             Thread.sleep(200);10             thread.stop();11            // thread.interrupt();12         }13     }14 }
View Code

  此时调用stop终止线程时,得到如下结果

  

User [id=1197577,name=1197576]User [id=1197577,name=1197576]User [id=1197577,name=1197576]User [id=1197577,name=1197576]User [id=1197578,name=1197577]

原因很简单:stop方法会释放对象锁,并终止线程,当线程还没有与name赋值时,已经被干掉了因此其他线程在读取时,很有可能读到NAME与ID值不一致的情况

 

二。守护线程Daemon

     守护线程顾名思义,是系统的守护者,这个线程为系统的运行默默提供服务,当系统任务运行完毕,守护线程也就完成使命了,比如说垃圾回收线程,JIT线程都是守护线程,设置守护线程的方式:在调用start方法前,通过线程对象.setDaemon(true)

代码如下:

关于java线程中stop interrupt daemon wait notify关于java线程中stop interrupt daemon wait notify
 1 package com.bdqn.lyrk.basic; 2  3 public class DaemonDemo { 4     public static class DaemonT extends Thread { 5         @Override 6         public void run() { 7             while (true){ 8                 System.out.println("I am alive"); 9                 try {10                     Thread.sleep(1000);11                 } catch (InterruptedException e) {12                     e.printStackTrace();13                 }14             }15         }16     }17 18     public static void main(String[] args) throws InterruptedException {19         DaemonT daemonT = new DaemonT();20         daemonT.setDaemon(true);21         daemonT.start();22         Thread.sleep(5000);23     }24 }
View Code

运行结果

I am aliveI am aliveI am aliveI am aliveI am aliveProcess finished with exit code 0

 

我们可以看到,当主线程执行完毕后,守护线程也随之结束

 

三。wait与notify

  wait与notify是多线程协同工作的最基本手段,可是这两个方法属于Object的方法,当需要使用wait和notify时,必须配合synchronized使用,此时调用wait方法,当前线程会进入等待队列并释放当前的对象锁,直到线程被唤醒(notify),notify方法会随机唤醒一个在等待队列中的线程,notifyAll方法则唤醒所有在等待队列中的线程

代码示例:

关于java线程中stop interrupt daemon wait notify关于java线程中stop interrupt daemon wait notify
 1 package com.bdqn.lyrk.basic; 2  3 public class SimpleWN { 4     public static final Object object = new Object(); 5  6     public static class T1 extends Thread { 7  8         @Override 9         public void run() {10             synchronized (object) {11                 System.out.println("开始执行线程...");12                 try {13                     object.wait();14                 } catch (InterruptedException e) {15                     e.printStackTrace();16                 }17                 System.out.println("结束执行线程...");18             }19         }20     }21 22     public static class T2 extends Thread {23         @Override24         public void run() {25             synchronized (object) {26                 System.out.println("5秒后准备唤醒线程..");27                 try {28                     Thread.sleep(5000);29                 } catch (InterruptedException e) {30                     e.printStackTrace();31                 }32                 object.notify();33             }34         }35     }36 37     public static void main(String[] args) {38         T1 t1 = new T1();39         T2 t2 = new T2();40         t1.start();41         t2.start();42     }43 }
View Code

输出内容:

开始执行线程...5秒后准备唤醒线程..结束执行线程...Process finished with exit code 0

注意以下几点: 

1)当线程T1被notify过后,也必须要重新获取对象锁,才能够继续执行

2)sleep也能达到wait的效果,但是唯一区别时,sleep时并不会释放对象锁,因此其他线程并没有得到执行的机会

版权声明

本文仅代表作者观点,不代表百度立场。
本文系作者授权百度百家发表,未经许可,不得转载。

热门文章
  • 机房智能化温湿度解决方式之POE供电以太网温湿度传感器

    机房智能化温湿度解决方式之POE供电以太网温湿度传感器
    机房智能化温湿度解决方式之POE供电以太网温湿度传感器 北京盈创力和电子科技有限公司 智能型TCP网口温湿度记录仪 北京IP网络温湿度记录仪厂家,北京盈创力和 北京智能型TCP网口温湿度记录仪IP网络温湿度记录仪是一种新型的基于TCP/IP协议双绞线以太网标准温湿度采集模块,利用它可以实现现场温度值、相对湿度值的采集,同时利用其自身的RJ45通信接口可以方便地和机房监控主机或交换机集线器进行联网。 工作于-40℃~85℃工业级带...
  • Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering

    Sequential Monte Carlo Methods (SMC) 序列蒙特卡洛/粒子滤波/Bootstrap Filtering
    Problem Statement 我们考虑一个具有马尔可夫性质、非线性、非高斯的状态空间模型(State Space Model):对于一个时间序列上的观测结果{yt,t∈N}\\{ y_t , t \\in N \\}{yt​,t∈N},我们认为每个观测结果yty_tyt​的生成依赖于一个无法直接观察的隐变量xt∈{xt,t∈N}x_t \\in \\{x_t , t \\in N \\}xt​∈{xt​,t∈N},即:p(...
  • HTTP状态保持的原理

    HTTP状态保持的原理
    a)在用户登录之后,浏览器返回响应的时候会在响应中添加上cookieb)浏览器接收到cookie之后会自动保存c)当用户再次请求同一服务器中的其他网页的时候,浏览器会自动带上之前保存的cookied)服务接收到请求之后可以请 request 对象中取到cookie 判断当前用户是否登录  Http是无状态的,就是连接时数据互通,关闭后...
  • Hive 系统函数及示例

    Hive 系统函数及示例
    查看所有系统函数 show functions; 函数分类 内置函数【系统函数】 数学函数: floor、round、ceil、cos、log2等 字符串函数: length、reverse、trim、lower、get_json_object、repeat等 收集函数: size 转换函数: cast 日期函数: year、month、datediff、date、date_add等 条件函数: coalesce、case…w...
  • CSRF的原理和防范措施

    CSRF的原理和防范措施
    a)攻击原理:i.用户C访问正常网站A时进行登录,浏览器保存A的cookieii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookieiv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以...
标签列表