IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> java基础巩固-宇宙第一AiYWM:为了维持生计,有个优雅的开始,你不得来个优雅的结束,对称美嘛(线程中有,RPC那块竟然也有,奇怪)~整起 -> 正文阅读

[网络协议]java基础巩固-宇宙第一AiYWM:为了维持生计,有个优雅的开始,你不得来个优雅的结束,对称美嘛(线程中有,RPC那块竟然也有,奇怪)~整起

这事还得从线程和RPC那里说起:
PART1:咱们之前多线程那里光知道一个线程启动的几种方式:new Thread、通过Runnable、通过Callable、通过线程池等等以及通过其他被封装好的但是底层还是前面几种方法搞出来线程的方式,不管是哪种【其实都是 想要启动线程需要调用 Thread 类的 start() 方法,并在 run() 方法中定义需要执行的任务。】,咱们确实没有好好看看线程优雅的停止这块,复习RPC那里的东西我突然想到这了,赶紧,整起…

  • 咱们一般不会手动停止一个线程,而是允许线程运行到结束,然后让它自然停止。不就是咱们经常干的事嘛,什么运行多长时间你这个线程滚蛋、什么跑完这个任务你滚蛋、哪个标志位变成什么样哪个方法被触发什么东西被XXX你这个线程滚蛋…。但是 依然会有许多特殊的情况需要我们提前停止线程,比如:用户突然关闭程序,或程序运行出错重启等。【在这种情况下,即将停止的线程在很多业务场景下仍然很有价值。尤其是我们想写一个健壮性很好,能够安全应对各种场景的程序时,正确停止线程就显得格外重要。但是Java 并没有提供简单易用,能够直接安全停止线程的能力。】
    • Java 停止线程的设计原则:对于 Java 而言,最正确的停止线程的方式是使用 interrupt。【关于interrupt,你在这篇文章中ctrl+F搜一下interrupt】。但是, interrupt 仅仅起到通知被停止线程的作用。而对于被停止的线程而言,它拥有完全的自主权,它既可以选择立即停止,也可以选择一段时间后停止,也可以选择压根不停止【Java 希望程序间能够相互通知、相互协作地管理线程】
      //在 while 循环体判断语句中,首先通过 Thread.currentThread().isInterrupt() 判断线程是否被中断
      while (!Thread.currentThread().isInterrupted() && more work to do) {
      	//随后检查是否还有工作要做
          do more work
      
      }
      
      • 【这道理很简单,因为如果不了解对方正在做的工作,贸然强制停止线程就可能会造成一些安全的问题,为了避免造成问题就需要给对方一定的时间来整理收尾工作。比如:线程正在写入一个文件,这时收到终止信号,它就需要根据自身业务判断,是选择立即停止,还是将整个文件写入成功后停止,而如果选择立即停止就可能造成数据不完整,不管是中断命令发起者,还是接收者都不希望数据出现问题。】
      • 对于 Java 而言,最正确的停止线程的方式是使用 interrupt,那错误的停止方式是什么呢?几种常见的停止线程的错误方法
        • 比如 stop(),suspend() 和 resume(),这些方法已经被 Java 直接标记为 @Deprecated。如果再调用这些方法,IDE 会友好地提示,我们不应该再使用它们了。那为什么Java 要把他们直接标记为 @Deprecated呢或者说为什么它们不能使用了呢
          • 是因为 stop() 会直接把线程停止,这样就没有给线程足够的时间来处理想要在停止前保存数据的逻辑,任务戛然而止,会导致出现数据完整性等问题
          • 而对于 suspend() 和 resume() 而言,它们的问题在于如果线程调用 suspend(),它并不会释放锁,就开始进入休眠,但此时有可能仍持有锁,这样就容易导致死锁问题,因为这把锁在线程被 resume() 之前,是不会被释放的。假设线程 A 调用了 suspend() 方法让线程 B 挂起,线程 B 进入休眠,而线程 B 又刚好持有一把锁,此时假设线程 A 想访问线程 B 持有的锁,但由于线程 B 并没有释放锁就进入休眠了,所以对于线程 A 而言,此时拿不到锁,也会陷入阻塞,那么线程 A 和线程 B 就都无法继续向下执行。
        • 用 volatile 标记位的停止方法也是错误的:
          • volatile 修饰标记位适用的场景:虽然volatile 修饰的标记位可以正常工作,但是如果我们说某个方法是正确的,那么它应该不仅仅是在一种情况下适用,而在其他情况下也应该是适用的
            在这里插入图片描述
          • volatile 修饰标记位不适用的场景:volatile 标记位的停止方法是不完美的
            • 首先声明一个生产者 Producer
              在这里插入图片描述
            • 消费者 Consumer
              在这里插入图片描述
            • 测试:
              在这里插入图片描述
      • 举个例子:
        在这里插入图片描述
      • 稍微回忆一下之前线程那里相关的一些知识:
        • 我们一旦调用某个线程的 interrupt() 之后,这个线程的中断标记位就会被设置成 true。每个线程都有这样的标记位,当线程执行时,应该定期检查这个标记位,如果标记位被设置成 true,就说明有程序想终止该线程
        • 如果 sleep、wait 等可以让线程进入阻塞的方法使线程休眠了,,而处于休眠中的线程被 interrupt() 中断,那么线程是可以感受到中断信号的,并且会抛出一个 InterruptedException 异常同时清除中断信号,将中断标记位设置成 false这样一来就不用担心长时间休眠中线程感受不到中断了,因为即便线程还在休眠,仍然能够响应中断通知,并抛出异常
          • 在实际开发中肯定是团队协作的,不同的人负责编写不同的方法,然后相互调用来实现整个业务的逻辑。那么如果我们负责编写的方法需要被别人调用,同时我们的方法内调用了 sleep 或者 wait 等能响应中断的方法时仅仅 catch 住异常是不够的【我们在实际开发中不能盲目吞掉中断,如果不在方法签名中声明,也不在 catch 语句块中再次恢复中断,而是在 catch 中不作处理,我们称这种行为是“屏蔽了中断请求”。如果我们盲目地屏蔽了中断请求,会导致中断信号被完全忽略,最终导致线程无法正确停止。】
            在这里插入图片描述
          • 捉到异常的 catch 没有进行任何处理逻辑,相当于把中断信号给隐藏了,这样做是非常不合理的,那么究竟应该怎么处理呢?
            • 首先,可以选择在方法签名中抛出异常
              在这里插入图片描述
            • 除了刚才推荐的将异常声明到方法签名中的方式外,还可以在 catch 语句中再次中断线程。
              在这里插入图片描述

PART2:在我的这篇:手写RPC~Version07(RPC原理、序列化框架们、网络协议框架们 、RPC 能帮助我们做什么呢、RPC异常排查:ctrl+F搜超时),笔记中说到,PRC框架有好几个府兵,其中一个站大门口的就是:(RPC 框架的)服务发现机制:
在这里插入图片描述
当然啦,真正的优雅停机,还得是下面这一部分:

  • (RPC 框架的)关闭流程:
    在这里插入图片描述

巨人的肩膀:
Java并发编程之美
Java并发编程实战
极客时间
徐隆曦老师的《Java 并发编程核心 78 讲》

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-10-31 12:34:57  更:2022-10-31 12:38:54 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 5:42:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计