Java并发04:Thread的基本方法(1)-Name、ThreadGroup、activeCount、isAlive、守护线程等
[超级链接:Java并发学习系列-绪论]
本章主要对Java中Thread类的基本方法进行学习。
1.序言
Thread类作为线程的基类,提供了一系列方法,主要有:
- Thread.sleep(long):强制线程睡眠一段时间。
- Thread.activeCount():获取当前程序中存活的线程数。
- thread.start():启动一个线程。
- Thread.currentThread():获取当前正在运行的线程。
- thread.getThreadGroup():获取线程所在线程组。
- thread.getName():获取线程的名字。
- thread.getPriority():获取线程的优先级。
- thread.setName(name):设置线程的名字。
- thread.setPriority(priority):设置线程的优先级。
- thread.isAlive():判断线程是否还存活着。
- thread.isDaemon():判断线程是否是守护线程。
- thread.setDaemon(true):将指定线程设置为守护线程。
- thread.join():在当前线程中加入指定线程,使得当前线程必须等待指定线程运行结束之后,才能结束。可以理解成
线程插队
、等待该线程终止
。 - thread.yield():使得当前线程退让出CPU资源,把CPU调度机会分配给同样线程优先级的线程。
- thread.interrupt():使得指定线程中断阻塞状态,并将阻塞标志位置为true。
- object.wai()、object.notify()、object.notifyAll():Object类提供的线程等待和线程唤醒方法。
为了便于阅读,将以上所有方法,放在5篇文章中进行学习。
本章主要学习绿色字体标记的方法。
1.Thread方法学习
1.1.线程休眠
Thread.sleep(long):强制线程睡眠一段时间,其中long的单位为毫秒。
线程休眠:休眠的时间可以用于让其他线程完成当前工作,亦可以减少CPU占用时间,但是不会释放锁持有的锁。可以理解成坐在座位上发呆。
示例代码:
//通过Thread.sleep(ms),指定当前线程进行休眠(但是并没有释放锁)
LOGGER.info("通过Thread.sleep(ms),指定当前线程进行休眠(但是并没有释放锁)");
LOGGER.info("现在时间:" + System.currentTimeMillis() + ",main线程即将休眠1000ms.");
Thread.sleep(1000);
LOGGER.info("休眠结束:" + System.currentTimeMillis() + "\n");
运行结果:
2018-03-12 11:46:06 INFO ThreadBasicDemo:20 - 通过Thread.sleep(ms),指定当前线程进行休眠(但是并没有释放锁)
2018-03-12 11:46:06 INFO ThreadBasicDemo:21 - 现在时间:1520826366873,main线程即将休眠1000ms.
2018-03-12 11:46:07 INFO ThreadBasicDemo:23 - 休眠结束:1520826367873
1.2.线程启动与存活线程数
Thread.activeCount():获取当前程序中存活的线程数。
thread.start():启动一个线程。
示例代码:
//通过Thread.activeCount(),获取程序活着的线程数。
LOGGER.info("通过Thread.activeCount(),获取程序活着的线程数");
LOGGER.info("当前程序活着的线程数:" + Thread.activeCount() + ",一个是main线程,一个是GC线程。");
//添加一个线程
new Thread(() -> {try {Thread.sleep(10);//存活10毫秒,方便后续代码能够统计到此线程} catch (InterruptedException e) {e.printStackTrace();}
}).start();
LOGGER.info("添加一个匿名线程之后,活着的线程数:" + Thread.activeCount());
Thread.sleep(15);//等着内部匿名线程死掉
LOGGER.info("匿名线程死掉之后,活着的线程数:" + Thread.activeCount() + "\n");
运行结果:
2018-03-12 11:46:07 INFO ThreadBasicDemo:26 - 通过Thread.activeCount(),获取程序活着的线程数
2018-03-12 11:46:07 INFO ThreadBasicDemo:27 - 当前程序活着的线程数:2,一个是main线程,一个是GC线程。
2018-03-12 11:46:07 INFO ThreadBasicDemo:36 - 添加一个匿名线程之后,活着的线程数:3
2018-03-12 11:46:07 INFO ThreadBasicDemo:38 - 匿名线程死掉之后,活着的线程数:2
关于Thread.sleep(long)在后续章节中还会继续学习。
1.3.当前线程、线程组、线程名、优先级、线程存活
Thread.currentThread():获取当前正在运行的线程。
thread.getThreadGroup():获取线程所在线程组。
thread.getName():获取线程的名字。
thread.getPriority():获取线程的优先级。
thread.setName(name):设置线程的名字。
thread.setPriority(priority):设置线程的优先级。
thread.isAlive():判断线程是否还存活着。
示例代码:
new Thread(() -> {//通过Thread.currentThread()获取当前线程LOGGER.info("通过Thread.currentThread()获取当前线程");Thread currentThread = Thread.currentThread();LOGGER.info("当前线程:" + currentThread);LOGGER.info("当前线程-名字(thread.getName()):" + currentThread.getName());LOGGER.info("当前线程-优先级(thread.getPriority()):" + currentThread.getPriority());LOGGER.info("当前线程-线程组名字:" + currentThread.getThreadGroup().getName() + "\n");//通过thread.setName(name)设置线程名LOGGER.info("通过thread.setName(name)设置线程名");currentThread.setName("张三");//通过thread.setPriority(priority)设置优先级LOGGER.info("通过thread.setPriority(priority)设置优先级");currentThread.setPriority(Thread.MAX_PRIORITY);LOGGER.info("修改名字和优先级之后:" + currentThread);//通过thread.isAlive()判断当前线程是否还活着LOGGER.info("通过thread.isAlive()判断当前线程是否还活着:" + currentThread.isAlive() + "\n");
}).start();
运行结果:
2018-03-12 11:46:07 INFO ThreadBasicDemo:42 - 通过Thread.currentThread()获取当前线程
2018-03-12 11:46:07 INFO ThreadBasicDemo:44 - 当前线程:Thread[Thread-1,5,main]
2018-03-12 11:46:07 INFO ThreadBasicDemo:45 - 当前线程-名字(thread.getName()):Thread-1
2018-03-12 11:46:07 INFO ThreadBasicDemo:46 - 当前线程-优先级(thread.getPriority()):5
2018-03-12 11:46:07 INFO ThreadBasicDemo:47 - 当前线程-线程组名字:main2018-03-12 11:46:07 INFO ThreadBasicDemo:50 - 通过thread.setName(name)设置线程名
2018-03-12 11:46:07 INFO ThreadBasicDemo:53 - 通过thread.setPriority(priority)设置优先级
2018-03-12 11:46:07 INFO ThreadBasicDemo:55 - 修改名字和优先级之后:Thread[张三,10,main]
2018-03-12 11:46:07 INFO ThreadBasicDemo:58 - 通过thread.isAlive()判断当前线程是否还活着:true
说明:
- 关于线程的字符串描述Thread[Thread-1,5,main],三个值分别代表:线程名、优先级和线程组名。
关于线程优先级在后续章节中还会继续学习。
1.4.守护线程的判断与设置
thread.isDaemon():判断线程是否是守护线程。
thread.setDaemon(true):将指定线程设置为守护线程。
守护线程:也可以称之为后台线程、非用户线程,即随系统结束而结束的线程。
更容易理解的说法:当前程序中,只剩下main线程和守护线程,且main线程执行完毕时,则系统结束。
与用户线程的区别:例如一个线程中通过while(true)无限等待。如果是用户线程,那么这个程序永远都不会关闭;如果是守护线程,那么当其他的用户线程执行完毕之后,程序及会关闭。
示例代码:
LOGGER.info("所谓[守护线程],可以理解为后台线程或非用户线程。");
LOGGER.info("当前程序中,只剩下main线程和守护线程,且main线程执行完毕时,系统结束。");
//守护线程
Thread normalThread = new Thread(() -> {try {while (true) {Thread.sleep(1000);LOGGER.info("normalThread线程正在工作...");}} catch (InterruptedException e) {e.printStackTrace();}
});
Thread daemonThread = new Thread(() -> {try {while (true) {Thread.sleep(1000);LOGGER.info("daemonThread线程正在工作...");}} catch (InterruptedException e) {e.printStackTrace();}
});
LOGGER.info("通过thread.isDaemon()判断当前线程[normalThread]是否是守护线程:" + normalThread.isDaemon());
LOGGER.info("通过thread.isDaemon()判断当前线程[daemonThread]是否是守护线程:" + daemonThread.isDaemon());
LOGGER.info("通过thread.setDaemon(true)将指定线程设置为守护线程,随main线程结束而结束。");
daemonThread.setDaemon(true);
LOGGER.info("通过thread.isDaemon()判断当前线程[daemonThread]是否是守护线程:" + daemonThread.isDaemon());
if (false) {normalThread.start();
} else {daemonThread.start();
}Thread.sleep(2000);//等待线程死掉
LOGGER.info("normalThread是否存活:" + normalThread.isAlive());
LOGGER.info("daemonThread是否存活:" + daemonThread.isAlive());
运行结果:
2018-03-12 11:46:08 INFO ThreadBasicDemo:62 - 所谓[守护线程],可以理解为后台线程或非用户线程。
2018-03-12 11:46:08 INFO ThreadBasicDemo:63 - 当前程序中,只剩下main线程和守护线程,且main线程执行完毕时,系统结束。
2018-03-12 11:46:08 INFO ThreadBasicDemo:85 - 通过thread.isDaemon()判断当前线程[normalThread]是否是守护线程:false
2018-03-12 11:46:08 INFO ThreadBasicDemo:86 - 通过thread.isDaemon()判断当前线程[daemonThread]是否是守护线程:false
2018-03-12 11:46:08 INFO ThreadBasicDemo:87 - 通过thread.setDaemon(true)将指定线程设置为守护线程,随main线程结束而结束。
2018-03-12 11:46:08 INFO ThreadBasicDemo:89 - 通过thread.isDaemon()判断当前线程[daemonThread]是否是守护线程:true
2018-03-12 11:46:09 INFO ThreadBasicDemo:79 - daemonThread线程正在工作...
2018-03-12 11:46:10 INFO ThreadBasicDemo:79 - daemonThread线程正在工作...
2018-03-12 11:46:10 INFO ThreadBasicDemo:97 - normalThread是否存活:false
2018-03-12 11:46:10 INFO ThreadBasicDemo:98 - daemonThread是否存活:true
Java并发04:Thread的基本方法(1)-Name、ThreadGroup、activeCount、isAlive、守护线程等相关推荐
- Java并发07:Thread的基本方法(4)-Thread.sleep()、Object.wait()、notify()和notifyAll()
[超级链接:Java并发学习系列-绪论] 本章主要对Java中Thread类的基本方法进行学习. 1.序言 Thread类作为线程的基类,提供了一系列方法,主要有: Thread.sleep(long ...
- Java并发编程—Thread类的start()方法是如何启动一个线程的?
目录 一:Java线程介绍 二:Java线程入口分析 三:Java线程的创建 四:总结 周末抽了点时间,研究了下HotSpot是如何创建Java线程的,顺便总结一下.文中引用的源码里删除很多细节,只保 ...
- 【java并发】AQS中acquire方法解析
AQS,全名AbstractQueuedSynchronizer(抽象队列同步器),它是CLH(不明白的可以先了解一下CLH)的变种.它与CLH不同之处在于: CLH是一种公平锁,它是通 ...
- Java并发编程的基础-interrupt方法
当其他线程通过调用当前线程的interrupt方法,表示向当前线程打个招呼,告诉他可以中断线程的执行了,至于什么时候中断,取决于当前线程自己. 线程通过检查资深是否被中断来进行相应,可以通过isInt ...
- Java并发编程78讲--29 第29讲:HahMap 为什么是线程不安全的?
本课时我们主要讲解为什么 HashMap 是线程不安全的?而对于 HashMap,相信你一定并不陌生,HashMap 是我们平时工作和学习中用得非常非常多的一个容器,也是 Map 最主要的实现类之一, ...
- java守护线程与用户线程_详解Java线程-守护线程与用户线程
干java 开发这么多年, 之前一直没留意java 进程还区分守护进程和用户进程.守护进程这个概念最早还是在linux系统中接触的,直到近期使用java开发心跳检测功能时,使用Timer时才发现原来j ...
- Java并发编程之interrupt方法使用
interrupt方法是Thread中的方法 以上是源码翻译,当线程调用interrupt时,会先检查是否有权限能够修改线程状态 然后再获取锁对象,再进行打断线程,在使用interrupt方法会情况线 ...
- Java 并发编程——Executor框架和线程池原理
Java 并发编程系列文章 Java 并发基础--线程安全性 Java 并发编程--Callable+Future+FutureTask java 并发编程--Thread 源码重新学习 java并发 ...
- activeMQ高并发发送消息异常解决方法
高并发发送消息异常解决方法: 现象:使用10个线程每100ms发送一条消息,大约3000多条后,出现异常,所有线程停 止: javax.jms.JMSException:Could not conne ...
- Java并发基础总结_Java并发编程笔记之基础总结(二)
一.线程中断 Java 中线程中断是一种线程间协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是需要被中断的线程根据中断状态自行处理. 1.void interrupt() 方法:中断线 ...
最新文章
- 16道嵌入式C语言面试题(经典) 预处理器(Preprocessor)
- Mysql5.7.20使用group by查询(select *)时出现错误--修改sql mode
- mysql sql时间比较_mysql和sql时间 字段比较大小的问题
- 【题解】Luogu P2157 [SDOI2009]学校食堂
- mysql pmm安装_PMM 安装部署
- Install Tcpping on Linux
- 7628刷breed_路由器刷breed_Web控制台助手v5.9版本.7z
- 后深度学习的挑战与思考(PRCV 焦李成 报告记录)
- RH236介绍红帽GLUSTER存储
- 狂神说Spring笔记(全网最全)
- C中Ascii码对照
- Foundry教程:使用多种方式编写可升级的智能代理合约(下)
- 向来痴,从此醉,先生一路走好。
- 给自己向前的动力“网上购车平台”帮忙实现
- D:/Vitis/export/RF47DR/RF47DRxpfm‘ is invalid. please choose a valid platform.
- Windows系统 lusrmgr命令详解,Windows命令行查看本地用户和组
- 双目测距+点云——使用MiddleBurry数据集的图片
- java程序向指定邮箱发邮件
- HarmonyOS_BearPi-HM Nano学习笔记之环境搭建
- 以太网性能测试仪-误码测试
热门文章
- 【CSS】【面试题】牛客网CSS专项练习部分答案及解析(更新中...)
- 2. 编写程序,计算下面公式并输出结果(a)编写一个函数计算 n! (b)编写主函数,由键盘输入n和m,调用(a)中的函数完成计算。(c)输入 n 和 m 要给出提示,并检查 n 和 m 的合理性
- php tab代码,PHP中实现crontab代码分享 -电脑资料
- Error:SyntaxError:JSON Parse error:Unexpected EOF 解决
- 全国大学生数据统计与分析竞赛2021年【专科组】-B题:基于 logistic 回归和聚类分析对用户消费行为价值分析
- 781. 森林中的兔子
- 12岁男孩发现Firefox严重漏洞获奖3000美元
- Splunk全新研究指明数据在优化业务结果方面的经济价值
- Vue 获取最近一周、当前周的日期
- Android 运营商与APN配置简介