[超级链接: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、守护线程等相关推荐

  1. Java并发07:Thread的基本方法(4)-Thread.sleep()、Object.wait()、notify()和notifyAll()

    [超级链接:Java并发学习系列-绪论] 本章主要对Java中Thread类的基本方法进行学习. 1.序言 Thread类作为线程的基类,提供了一系列方法,主要有: Thread.sleep(long ...

  2. Java并发编程—Thread类的start()方法是如何启动一个线程的?

    目录 一:Java线程介绍 二:Java线程入口分析 三:Java线程的创建 四:总结 周末抽了点时间,研究了下HotSpot是如何创建Java线程的,顺便总结一下.文中引用的源码里删除很多细节,只保 ...

  3. 【java并发】AQS中acquire方法解析

    AQS,全名AbstractQueuedSynchronizer(抽象队列同步器),它是CLH(不明白的可以先了解一下CLH)的变种.它与CLH不同之处在于:        CLH是一种公平锁,它是通 ...

  4. Java并发编程的基础-interrupt方法

    当其他线程通过调用当前线程的interrupt方法,表示向当前线程打个招呼,告诉他可以中断线程的执行了,至于什么时候中断,取决于当前线程自己. 线程通过检查资深是否被中断来进行相应,可以通过isInt ...

  5. Java并发编程78讲--29 第29讲:HahMap 为什么是线程不安全的?

    本课时我们主要讲解为什么 HashMap 是线程不安全的?而对于 HashMap,相信你一定并不陌生,HashMap 是我们平时工作和学习中用得非常非常多的一个容器,也是 Map 最主要的实现类之一, ...

  6. java守护线程与用户线程_详解Java线程-守护线程与用户线程

    干java 开发这么多年, 之前一直没留意java 进程还区分守护进程和用户进程.守护进程这个概念最早还是在linux系统中接触的,直到近期使用java开发心跳检测功能时,使用Timer时才发现原来j ...

  7. Java并发编程之interrupt方法使用

    interrupt方法是Thread中的方法 以上是源码翻译,当线程调用interrupt时,会先检查是否有权限能够修改线程状态 然后再获取锁对象,再进行打断线程,在使用interrupt方法会情况线 ...

  8. Java 并发编程——Executor框架和线程池原理

    Java 并发编程系列文章 Java 并发基础--线程安全性 Java 并发编程--Callable+Future+FutureTask java 并发编程--Thread 源码重新学习 java并发 ...

  9. activeMQ高并发发送消息异常解决方法

    高并发发送消息异常解决方法: 现象:使用10个线程每100ms发送一条消息,大约3000多条后,出现异常,所有线程停 止: javax.jms.JMSException:Could not conne ...

  10. Java并发基础总结_Java并发编程笔记之基础总结(二)

    一.线程中断 Java 中线程中断是一种线程间协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是需要被中断的线程根据中断状态自行处理. 1.void interrupt() 方法:中断线 ...

最新文章

  1. 16道嵌入式C语言面试题(经典) 预处理器(Preprocessor)
  2. Mysql5.7.20使用group by查询(select *)时出现错误--修改sql mode
  3. mysql sql时间比较_mysql和sql时间 字段比较大小的问题
  4. 【题解】Luogu P2157 [SDOI2009]学校食堂
  5. mysql pmm安装_PMM 安装部署
  6. Install Tcpping on Linux
  7. 7628刷breed_路由器刷breed_Web控制台助手v5.9版本.7z
  8. 后深度学习的挑战与思考(PRCV 焦李成 报告记录)
  9. RH236介绍红帽GLUSTER存储
  10. 狂神说Spring笔记(全网最全)
  11. C中Ascii码对照
  12. Foundry教程:使用多种方式编写可升级的智能代理合约(下)
  13. 向来痴,从此醉,先生一路走好。
  14. 给自己向前的动力“网上购车平台”帮忙实现
  15. D:/Vitis/export/RF47DR/RF47DRxpfm‘ is invalid. please choose a valid platform.
  16. Windows系统 lusrmgr命令详解,Windows命令行查看本地用户和组
  17. 双目测距+点云——使用MiddleBurry数据集的图片
  18. java程序向指定邮箱发邮件
  19. HarmonyOS_BearPi-HM Nano学习笔记之环境搭建
  20. 以太网性能测试仪-误码测试

热门文章

  1. 【CSS】【面试题】牛客网CSS专项练习部分答案及解析(更新中...)
  2. 2. 编写程序,计算下面公式并输出结果(a)编写一个函数计算 n! (b)编写主函数,由键盘输入n和m,调用(a)中的函数完成计算。(c)输入 n 和 m 要给出提示,并检查 n 和 m 的合理性
  3. php tab代码,PHP中实现crontab代码分享 -电脑资料
  4. Error:SyntaxError:JSON Parse error:Unexpected EOF 解决
  5. 全国大学生数据统计与分析竞赛2021年【专科组】-B题:基于 logistic 回归和聚类分析对用户消费行为价值分析
  6. 781. 森林中的兔子
  7. 12岁男孩发现Firefox严重漏洞获奖3000美元
  8. Splunk全新研究指明数据在优化业务结果方面的经济价值
  9. Vue 获取最近一周、当前周的日期
  10. Android 运营商与APN配置简介