热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ThreadRunnable线程及stop()、interrupt()、sleep()等方法讲解

如何开启线程开启线程2种方式:自定义类继承Thread类,重写run方法;new自定义类().start()自定义类实现Runnab
  • 如何开启线程

开启线程2种方式:

自定义类继承Thread类,重写run方法;new 自定义类().start()

自定义类实现Runnable接口,实现run方法;new Thread(new 自定义类()).start()

  • Thread和Runable

Thread是对线程的抽象封装,完成独立完成某个任务的调度,包括任务的开始、暂停、结束等操作。本身是实现Runnable接口,所以具有Runnable的所有功能。

Runnable 是对任务的抽象封装,业务任务的具体逻辑封装。本身不具有独立资源调度。需要Thread协助完成,这也就是前面说的开启线程需要先new Thread() 通过参数把Runnable传递进去。

  • JVM开启,默认开启哪些线程(JDK1.8为例)

public static void main(String[] args) {//虚拟机线程系统的管理接口(JVM开启的线程);对JVM系统进行监控时,使用类ManagementFactoryThreadMXBean threadMXBean= ManagementFactory.getThreadMXBean();ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);for(ThreadInfo threadInfo:threadInfos){System.out.println("["+threadInfo.getThreadId()+"]"+threadInfo.getThreadName());}/* 一般项目启动会启动的线程有:* [8]JDWP Command Reader[7]JDWP Event Helper Thread[6]JDWP Transport Listener: dt_socket[5]Attach Listener[4]Signal Dispatcher[3]Finalizer 线程管理Object finalize()方法,每个对象销毁时都会调用这个方法;不推荐在这个方法中写资源释放,有时调用不到(main结束这个线程也就没有了)[2]Reference Handler[1]main 主线程,线程关闭其他线程会依次关闭* */}

  • stop/interrupt/sleep等方法总结

stop():结束线程,比较野蛮会立即结束线程。比如当前线程正在写一个文件,或者正在写入数据库,正在完成一半任务时,接到stop命令,立即线程结束,导致文件不完整,错误的文件或数据库数据不完整等问题。所以JDK1.8之后不在推荐使用。当然如果能够保证当前线程没有这些类似任务,采用stop停止线程也是可以的。

interrupt():标记线程状态为中断状态(线程本身并不会结束),此时线程中如果有join、wait、sleep等方法调用的时候会抛出异常java.lang.InterruptedException。在线程的run()方法中我们需要自己写逻辑结束线程。isInterrupt()可获取线程的中断状态。Thread.interrupt()静态方法内部会调用当前线程的isinterrupt()方法,但是内部也会再次把状态标志位修改,所有一般都是用实例interrupt方法。对于Runnable实例化的线程,一般用Thread.currentThread().interrupt() 方法判断。

sleep():使当前线程进入阻塞状态。同时这个方法内部会监测interrupt状态,如果当前线程中断后,同时线程还睡眠时,会报异常java.lang.InterruptedException: sleep interrupted。sleep()并不会释放对象锁,只有锁代码块执行完后,其他线程才能够获取锁

  • 线程stop方法案例

import java.util.concurrent.TimeUnit;/*** @ClassName xu01* @Description des* @Author zyk* @Date 2019/9/24* @Version 1.0**/
public class xu01 {private static class UseThread extends Thread{@Overridepublic void run() {while(true) {System.out.println("正在写入文件,写入部分...");}}}public static void main(String[] args) {UseThread useThread=new UseThread();useThread.start();//main线程睡眠20try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}//main线程2秒后关闭// 1:stop() 是一个@Deprecated不推荐使用,过于野蛮停止线程(会出现线程写部分文件就挂了)useThread.stop();System.out.println("main 线程结束");}
}

  • 线程interrupt方法案例

import java.util.concurrent.TimeUnit;/*** @ClassName xu01* @Description des* @Author zyk* @Date 2019/9/24* @Version 1.0**/
public class xu01 {private static class UseThread extends Thread{@Overridepublic void run() {while(true) {System.out.println("正在写入文件,写入部分...");//判断线程状态是否,是否需要结束// if(isInterrupted()){//Thread.interrupted静态方法也是同样的功能,内部会获取当前线程if(Thread.interrupted()){System.out.println("线程状态:"+interrupted());System.out.println("判断当前文件写完了,然后结束线程,不会导致文件是个损坏的文件");break;}}}}public static void main(String[] args) {UseThread useThread=new UseThread();useThread.start();//main线程睡眠20try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}//main线程2秒后关闭//只是标记线程标志位为中断状态,需要在run方法中写逻辑结束线程,否则线程还是不能够结束useThread.interrupt();System.out.println("main 线程结束");}
}

  • 线程sleep方法案例

在线程中添加sleep睡眠逻辑,做完一件事后睡眠一段时间,再次做事情。

import java.util.concurrent.TimeUnit;/*** @ClassName xu01* @Description des* @Author zyk* @Date 2019/9/24* @Version 1.0**/
public class xu01 {private static class UseThread extends Thread{@Overridepublic void run() {while(true) {System.out.println("正在做某件任务...");System.out.println("结束一段任务后,线程睡眠一段时间");try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}if(Thread.interrupted()){System.out.println("线程状态:"+interrupted());System.out.println("判断当前文件写完了,然后结束线程,不会导致文件是个损坏的文件");break;}}}}public static void main(String[] args) {UseThread useThread=new UseThread();useThread.start();//main线程睡眠20try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}//main线程2秒后关闭//只是标记线程标志位为中断状态,需要在run方法中写逻辑结束线程,否则线程还是不能够结束useThread.interrupt();System.out.println("main 线程结束");}
}

注意:这样线程并不会结束,运行结果如下

正在做某件任务...
结束一段任务后,线程睡眠一段时间
java.lang.InterruptedException: sleep interruptedat java.lang.Thread.sleep(Native Method)at java.lang.Thread.sleep(Thread.java:340)at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)at controller.multithread.xu01$UseThread.run(xu01.java:21)
main 线程结束
正在做某件任务...
结束一段任务后,线程睡眠一段时间
正在做某件任务...
结束一段任务后,线程睡眠一段时间

这是因为 TimeUnit.MILLISECONDS.sleep(20);会抛出异常后,把当前线程中断状态又改回去了,导致线程还会继续执行。

需要修改代码:第一种方式,在sleep方法上添加try-catch,在InterruptedException异常代码块中再次调用interrupte()方法。第二种方式,把while死循环监视起来,出现InterruptedException 异常后结束线程,修改后代码如下:

import java.util.concurrent.TimeUnit;/*** @ClassName xu01* @Description des* @Author zyk* @Date 2019/9/24* @Version 1.0**/
public class xu01 {private static class UseThread extends Thread{@Overridepublic void run() {try {while (true) {System.out.println("正在做某件任务...");System.out.println("结束一段任务后,线程睡眠一段时间");try {TimeUnit.MILLISECONDS.sleep(20);//java.lang.InterruptedException: sleep interrupted 需要把这个异常抛出去} catch (InterruptedException e) {//interrupt();throw e;}if (Thread.interrupted()) {System.out.println("线程状态:" + interrupted());System.out.println("判断当前文件写完了,然后结束线程,不会导致文件是个损坏的文件");break;}}}catch (InterruptedException e){e.printStackTrace();System.out.println("子线程结束");}}}public static void main(String[] args) {UseThread useThread=new UseThread();useThread.start();//main线程睡眠20try {TimeUnit.MILLISECONDS.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}//main线程2秒后关闭//只是标记线程标志位为中断状态,需要在run方法中写逻辑结束线程,否则线程还是不能够结束useThread.interrupt();System.out.println("main 线程结束");}
}

  • 线程池使用

JDK1.8不在推荐使用Executors创建线程了,推荐使用ThreadPoolExecutor,可控制最大线程数量。而Executors 最多创建线程数量是 Integer.MAX_VALUE 会导致系统OOM问题

public static void main(String[] args) throws ExecutionException, InterruptedException {int count=230;//线程池1:ExecutorService pool1=Executors.newCachedThreadPool();ExecutorService pool2=Executors.newFixedThreadPool(5);//线程池2:ThreadFactory namedThreadFactory=new ThreadFactoryBuilder().setNameFormat("jake-pool-%d").build();ExecutorService pool=new ThreadPoolExecutor(5,200,60L,TimeUnit.SECONDS,new LinkedBlockingQueue(1024),namedThreadFactory,new ThreadPoolExecutor.AbortPolicy());for(int i=0;i{System.out.println("========线程名称:"+Thread.currentThread().getName());});}pool.shutdown();System.out.println("shutdown");}

 


推荐阅读
  • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • MQTT技术周报:硬件连接与协议解析
    本周开发笔记重点介绍了在新项目中使用MQTT协议进行硬件连接的技术细节,涵盖其特性、原理及实现步骤。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 本文详细记录了在基于Debian的Deepin 20操作系统上安装MySQL 5.7的具体步骤,包括软件包的选择、依赖项的处理及远程访问权限的配置。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • ImmutableX Poised to Pioneer Web3 Gaming Revolution
    ImmutableX is set to spearhead the evolution of Web3 gaming, with its innovative technologies and strategic partnerships driving significant advancements in the industry. ... [详细]
author-avatar
手机用户2502880041
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有