首页 > 编程语言 >java线程的interrup、tUninterruptibles.sleepUninterruptibly和sleep、wait

java线程的interrup、tUninterruptibles.sleepUninterruptibly和sleep、wait

时间:2023-02-15 13:34:08浏览次数:57  
标签:java Thread 中断 sleepUninterruptibly 线程 interrupt 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

  1. 这两个方法来自不同的类,sleep方法属于Thread,wait方法属于Object。
  2. 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
  3. 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,Thread,中断,sleepUninterruptibly,线程,interrupt,sleep,wait
From: https://www.cnblogs.com/cgy1995/p/17122484.html

相关文章

  • c++ 程序通用多线程单例设计 c++ web 框架设计经验谈
    设计c++web框架时候,想要一个框架缓存类,很多通用缓存类是用字符保存,作为框架内置就不要序列和反序列了,因为框架内部使用。想给自己的paozhuc++web框架添加缓存类,参考......
  • 线程同步和线程通信
    Synchronized锁和Lock锁机制解决线程同步问题,及wait和notify实现线程间通信的简要介绍Author:MsuenbDate:2023-02-15线程同步当我们使用多个线程访问同一资源(可以......
  • javascript放在head和body的区别以及js文件加载带来的阻塞解决
    今天在看到菜鸟教程中的HTML中的Javascript脚本代码必须位于<script>与</script>标签之间。Javascript脚本代码可被放置在HTML页面的<body>和<head>部分中......
  • java File
     CreateTime--2017年10月31日10:14:24Author:Marydonjava操作File类importjava.io.File;1.创建一个文件方式一:语法:Filefile=newFile(absolutePath);说明:只传一个参数,......
  • java 下载网络图片
     java如何下载网络图片CreateTime--2017年9月30日11:18:19Author:Marydon说明:根据网络URL获取该网页上面所有的img标签并下载符合要求的所有图片所需jar包:jsoup.jarimport......
  • JAVA中的Comparable接口和自定义比较器
    Java中的自然排序自然排序定制排序自然排序TreeSet集合在存储数据时有一定的顺序,它会将一些数据进行比较,比较调用的是comparaTo()方法,该方法是在Comparable中定义的,自然排......
  • Java NIO:Buffer、Channel 和 Selector详解
    本来要一起介绍非阻塞IO和JDK7的异步IO的,不过因为之前的文章真的太长了,有点影响读者阅读,所以这里将它们放到另一篇文章中进行介绍。Buffer一个Buffer本质上是内存......
  • 重学Java-第六章 Java运算符
    6.1算术运算符​ Java语言提供了执行加减乘除四则运算的运算符。算数运算符被用在数学表达式中,可以使用任意嵌套的小括号,其作用与数学中相同。下表列出了算术运算符:......
  • 重学Java-第二章 Java快速入门
    2.1在Windows上安装Java2.1.1下载安装包打开Oracle官网的JDK下载地址,推荐下载JDK1.8版本,1.8版本是目前企业使用最多的版本,下拉找到Java8,选择windows平台。​ ......
  • 重学Java-第三章 Java基本语法
    3.1基本语法​ 编写Java程序时,应注意以下几点:大小写敏感:Java是对大小写敏感的,这就表示标识符Hello和hello是不同的。类名:对所有的类来说,类名的首字母应大写,若类名由......