java线程的interrup、tUninterruptibles.sleepUninterruptibly和sleep、wait
参考:
(1)https://blog.csdn.net/qq_36031640/article/details/116696685
(2)https://blog.csdn.net/liuxiao723846/article/details/77882011
一、线程的interrupted:
一个正在运行的线程除了正常的时间片中断之外,能否被其他线程控制?或者说其他线程能否让指定线程放弃CPU或者提前结束运行? 除了线程同步机制之外,还有两种方法:
(1) Thread.stop(), Thread.suspend(), Thread.resume() 和Runtime.runFinalizersOnExit() 这些终止线程运行的方法 。这些方法已经被废弃,使用它们是极端不安全的。
(2) Thread.interrupt() 方法是很好的选择。但是使用的时候我们必须好好理解一下它的用处。
1、无法中断正在运行的线程代码:
class TestRunnable implements Runnable{
public void run(){
while(true)
{
System.out.println( "Thread is running..." );
long time = System.currentTimeMillis();//去系统时间的毫秒数
while((System.currentTimeMillis()-time < 1000)) {
//程序循环1秒钟,不同于sleep(1000)会阻塞进程。
}
}
}
}
public class ThreadDemo{
public static void main(String[] args){
Runnable r=new TestRunnable();
Thread th1=new Thread(r);
th1.start();
th1.interrupt();
}
}
//运行结果:一秒钟打印一次Thread is running...。程序没有终止的任何迹象
上面的代码说明interrupt()并没有中断一个正在运行的线程,或者说让一个running中的线程放弃CPU。那么interrupt到底中断什么。
首先我们看看interrupt究竟在干什么?当我们调用th1.interrput()的时候,线程th1的中断状态(interrupted status) 会被置位。我们可以通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态。
2、通过Thread.currentThread().isInterrupted() 来检查这个布尔型的中断状态:
//Interrupted的经典使用代码
public void run(){
try{
....
while(!Thread.currentThread().isInterrupted()&& more work to do){
// do more work;
}
}catch(InterruptedException e){
// thread was interrupted during sleep or wait
}
finally{
// cleanup, if required
}
}
很显然,在上面代码中,while循环有一个决定因素就是需要不停的检查自己的中断状态。当外部线程调用该线程的interrupt 时,使得中断状态置位。这是该线程将终止循环,不在执行循环中的do more work了。这说明: interrupt中断的是线程的某一部分业务逻辑,前提是线程需要检查自己的中断状态(isInterrupted())。
3、但是当th1被阻塞的时候,比如被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞时。调用它的interrput()方法。可想而知,没有占用CPU运行的线程是不可能给自己的中断状态置位的。这就会产生一个InterruptedException异常。
//中断一个被阻塞的线程代码
class TestRunnable implements Runnable{
public void run(){
try{
Thread.sleep(1000000); //这个线程将被阻塞1000秒
}catch(InterruptedException e){
e.printStackTrace();
//do more work and return.
}
}
}
public class TestDemo2{
public static void main(String[] args) {
Runnable tr=new TestRunnable();
Thread th1=new Thread(tr);
th1.start(); //开始执行分线程
while(true){
th1.interrupt(); //中断这个分线程
}
}
}
/*运行结果:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at TestRunnable.run(TestDemo2.java:4)
at java.lang.Thread.run(Unknown Source)*/
二、sleep和wait区别以及Uninterruptibles.sleepUninterruptibly
- 这两个方法来自不同的类,sleep方法属于Thread,wait方法属于Object。
- 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
- wait, notify和notifyAll只能在同步控制方法(synchronized)或者同步控制块里面使用,而sleep可以在任何地方使用。
一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在 sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有finally语句块)以及以后的代码。
一个对象调用了wait方法,必须要采用notify()和notifyAll()方法唤醒该进程。如果线程拥有某个或某些对象的同步锁,那么在调用了wait()后,这个线程就会释放它持有的所有同步资源,而不限于这个被调用了wait()方法的对象。从而使线程所在对象中的其它synchronized数据可被别的线程使用。 wait()方法也同样会在wait的过程中有可能被其他对象调用interrupt()方法而产生InterruptedException,效果以及处理方式同sleep()方法。
Uninterruptibles.sleepUninterruptibly(100, TimeUnit.MILLISECONDS);
该改法对sleep期间被中断的异常做了捕获,并计算出剩余需要sleep的时间,然后继续等待,直到耗尽所有时间。所以这个方法可以描述为不可中断的sleep。其意义是为了支持上层限流对于请求的控制。
java线程的interrup、tUninterruptibles.sleepUninterruptibly和sleep、wait的更多相关文章
- java线程池源码分析
我们在关闭线程池的时候会使用shutdown()和shutdownNow(),那么问题来了: 这两个方法又什么区别呢? 他们背后的原理是什么呢? 线程池中线程超过了coresize后会怎么操作呢? 为 ...
- Java线程并发:知识点
Java线程并发:知识点 发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备 ...
- Java线程的概念
1. 计算机系统 使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行:当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了. 缓 ...
- Java 线程池框架核心代码分析--转
原文地址:http://www.codeceo.com/article/java-thread-pool-kernal.html 前言 多线程编程中,为每个任务分配一个线程是不现实的,线程创建的开销和 ...
- 细说进程五种状态的生老病死——双胞胎兄弟Java线程
java线程的五种状态其实要真正高清,只需要明白计算机操作系统中进程的知识,原理都是相同的. 系统根据PCB结构中的状态值控制进程. 单CPU系统中,任一时刻处于执行状态的进程只有一个. 进程的五种状 ...
- 【转载】 Java线程面试题 Top 50
Java线程面试题 Top 50 不管你是新程序员还是老手,你一定在面试中遇到过有关线程的问题.Java语言一个重要的特点就是内置了对并发的支持,让Java大受企业和程序员 的欢迎.大多数待遇丰厚的J ...
- 第24章 java线程(3)-线程的生命周期
java线程(3)-线程的生命周期 1.两种生命周期流转图 ** 生命周期:**一个事物冲从出生的那一刻开始到最终死亡中间的过程 在事物的漫长的生命周期过程中,总会经历不同的状态(婴儿状态/青少年状态 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- 第22章 java线程(2)-线程同步
java线程(2)-线程同步 本节主要是在前面吃苹果的基础上发现问题,然后提出三种解决方式 1.线程不安全问题 什么叫线程不安全呢 即当多线程并发访问同一个资源对象的时候,可能出现不安全的问题 对于前 ...
- 第21章 java线程(1)-线程初步
java线程(1)-线程初步 1.并行和并发 并行和并发是即相似又有区别: 并行:指两个或者多个事件在同一时刻点发生. 并发:指两个或多个事件在同一时间段内发生 在操作系统中,并发性是指在一段事件内宏 ...
随机推荐
- K8s Pod状态与容器探针
1.pod的调度流程及常见状态 1.1.pod的调度流程 Pod创建过程如上图所示,首先用户向apiserver发送创建pod的请求,apiserver收到用于创建pod请求后,对应会对该用户身份信息 ...
- 快速上手kettle(三)壶中可以放些啥?
目录 序言 一 .kettle这壶能装些啥 二.Access输入 2.1 准备Acess数据库和表 2.2 新建一个转换并设置 2.3 启动转换预览数据 三.CSV文件输入 3.1 准备csv文件,并 ...
- Python 列表、字典、元组的一些小技巧
1. 字典排序 我们知道 Python 的内置 dictionary 数据类型是无序的,通过 key 来获取对应的 value.可是有时我们需要对 dictionary 中的 item 进行排序输出, ...
- 【C#/.NET】record介绍
目录 什么是record? 使用record record解构 record原理 结论 什么是record? record是.NET 5中的一种新特性,可以看作是一种概念上不可变的类.recor ...
- 【python基础】复杂数据类型-字典(遍历)
一个字典可能只包含几个键值对,也可能包含数百万个键值对,所以Python支持字典遍历.字典可用于以各种方式存储信息,因此有多种遍历字典的方式:可遍历字典的所有键值对.键或值. 1.遍历所有的键值对 其 ...
- 文献精读1:SpikTransformer
Spikformer code source(pku):GitHub - ZK-Zhou/spikformer: ICLR 2023, Spikformer: When Spiking Neural ...
- Kubernetes(k8s) 资源限制:resources,LimitRange,ResourceQuota
目录 一.系统环境 二.前言 三.Kubernetes资源限制简介 四.创建没有资源限制的pod 4.1 创建没有资源限制的pod 4.2 内存消耗测试 五.使用resources字段配置资源限制 5 ...
- flutter小白是如何在一周内用chatGPT开发一款App的
创作初衷 这篇文章创作的初衷,只是为了写一个有关日历类的软件供自己使用,考虑到自己从来还没有使用flutter正式创作一个app,因此磨刀霍霍想试一试. 至于为什么要做一款日历软件,因为发现市面上的关 ...
- 5.2 基于ROP漏洞挖掘与利用
通常情况下栈溢出可能造成的后果有两种,一类是本地提权另一类则是远程执行任意命令,通常C/C++并没有提供智能化检查用户输入是否合法的功能,同时程序编写人员在编写代码时也很难始终检查栈是否会发生溢出,这 ...
- java根据配置文件读取值
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> <dependency> ...