转载请标明出处:
http://blog.csdn.net/hai_qing_xu_kong/article/details/70339618
本文出自:【顾林海的博客】

前言

在上一篇文章《有关线程的相关知识(1)》 一文中已经讲了线程的两种创建方式以及6个状态,这篇文章就把接下来的东西加上,各位看官,提好裤子,上车咯。

线程的中断

在java中,当所有非守护进程运行结束或是其中一个线程调用了System.exit()方法时java程序就运行结束,这里面的守护线程是一种特殊的线程,它是系统的守护者,在后台默默地完成一些系统性的服务,比如垃圾回收线程、JIT线程(动态编译器)就可以理解为守护线程,如果守护线程要守护的对象已经不存在了,那么整个应用程序就会结束,也就是说,在Java应用中如果只剩下守护线程时,Java虚拟机就会自然退出。

我们来编写这样一个程序,创建一个线程,在这个线程中一直打印信息,接着我们给这个线程设置为守护线程,并在主线程中休眠2秒后,看看创建的线程是否继续打印:

public class Daemon implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){System.out.println("hello....");try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
public class Client {public static void main(String[] args) {Thread daemonThread=new Thread(new Daemon());daemonThread.setDaemon(true);daemonThread.start();try {Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}

输出的结果:

hello….
hello….
hello….

可以发现将daemonThread设置为守护线程,系统中只有主线程main为用户线程,在main线程休眠2秒后退出,整个程序也结束,如果不把daemonThread设置为守护线程,main线程结束后,daemonThread线程会不停的打印,永远不会结束。

在Java中提供了中断机制,可以使用它来结束一个线程,这种机制要求线程检查它是否被中断,然后决定是不是响应这个中断请求,并且线程是可以忽略这个中断请求。

接下来创建一个线程并不停打印累加的number值,在打印前先判断当前线程是否被中断,如果被中断,就打印信息,接着退出。

public class MyThread extends Thread{private int number=0;@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){if(isInterrupted()){System.out.println("interrupted...");return;}System.out.println("number="+number);number++;}}}
public class Client {public static void main(String[] args) {MyThread myThread=new MyThread();myThread.start();try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}myThread.interrupt();}
}

输出:

…………………..
number=465110
number=465111
number=465112
interrupted…

可以看出当myThread线程被中断后,程序就运行终止,Thread类有一个表明线程是否被中断的属性,类型是布尔值,当线程的interrupt()方法被调用时,这个属性就会被赋值为true。

isInterrupted()会返回上面提到的属性值,除了使用isInterrupted()方法检查线程是否被中断,还有一个方法interrupted()也是检查线程的中断与否,两种方法的区别在与:isInterrupted()不能改变interrupted属性的值,但interrupted()方法能设置interrupted 属性为false。

线程的休眠与恢复

线程提供一个sleep()方法,表示休眠,在休眠的这段时间,线程不占用计算机的任何资源,sleep()方法接受整型数值作为参数,来表明线程挂起执行的毫秒数。sleep()方法的另一种使用方式是通过 TimeUnit枚举类元素进行调用,它接受的参数单位是秒,最后会被转化成毫秒。

在接下来的程序中,通过TimeUnit类的SECONDS属性的sleep()方法来挂起一秒钟,之后输出信息。

public class MyThread extends Thread{private int number=0;@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){            System.out.println("number="+number);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {System.out.println("InterruptedException...");}number++;}}}
public class Client {public static void main(String[] args) {MyThread myThread=new MyThread();myThread.start();try {TimeUnit.SECONDS.sleep(5);} catch (InterruptedException e) {e.printStackTrace();}myThread.interrupt();}
}

在主类中,我们运行这个线程并在挂起一段时间后中断这个线程,我们在myThread线程中的调用sleep()方法时捕获InterruptedException异常时输出一段信息(推荐当线程被中断时,可以在捕获这个异常时进行释放或者关闭线程正在使用的资源)。

输出:

number=2
number=3
number=4
InterruptedException…
number=5
number=6
number=7
number=8
…………….
…………….

除了sleep()方法外,Java并发API还提供了另一个方法来使线程对象释放CPU,这个方法是yield()方法,它会通知JVM这个线程对象可以释放CPU了,但JVM并不保证遵循这个要求。

等待线程的终止

有时候,我们需要等待线程的终止,比如初始化资源,只有在初始化完毕后才能继续执行下去,达到这个目的,我们可以使用Thread类的join()方法,当一个线程对象调用join()方法时,调用它当线程将被挂起,直到这个线程对象完成它当任务。

我们创建两个个线程,其中每隔一秒计数,当第一个线程到达5并且第二线程到达6时,主线程才能继续执行下去。

public class MyThread1 extends Thread{private int number=0;@Overridepublic void run() {// TODO Auto-generated method stubwhile(number<=5){           System.out.println("number="+number);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {System.out.println("InterruptedException...");}number++;}}}
public class MyThread2 extends Thread{private int number=0;@Overridepublic void run() {// TODO Auto-generated method stubwhile(number<=6){           System.out.println("number="+number);try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {System.out.println("InterruptedException...");}number++;}}}
public class Client {public static void main(String[] args) {MyThread1 myThread1=new MyThread1();MyThread2 myThread2=new MyThread2();myThread1.start();myThread2.start();try {myThread1.join();myThread2.join();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("终于轮到我了.....");}
}

输出:

number=0
number=0
number=1
number=1
number=2
number=2
number=3
number=3
number=4
number=4
number=5
number=5
number=6
终于轮到我了…..

当myThread1与myThread2都结束时,主线程对象才会继续执行下去。

线程的分组

Java并发API提供了一个功能,能够把线程分组,这样的话,一组线程可以当作一个单一的单元 , Java提供了ThreadGroup类表示一组线程,线程组可以包含线程对象,也可以包含其他的线程组对象,它是一个树形结构。

public class ThreadGroupClient implements Runnable{@Overridepublic void run() {while(true){System.out.println("group:"+Thread.currentThread().getThreadGroup().getName()+"----thread:"+Thread.currentThread().getName());try {TimeUnit.SECONDS.sleep(1);} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {ThreadGroup threadGroup=new ThreadGroup("group");Thread thread1=new Thread(new ThreadGroupClient(),"thread1");Thread thread2=new Thread(new ThreadGroupClient(),"thread2");thread1.start();thread2.start();System.out.println(threadGroup.activeCount());threadGroup.list();}}

输出:

0
group:main—-thread:thread2
group:main—-thread:thread1
java.lang.ThreadGroup[name=group,maxpri=10]
group:main—-thread:thread1
group:main—-thread:thread2
group:main—-thread:thread1
group:main—-thread:thread2

创建一个名叫group的线程组,并将thread1和thread2加入这个线程组中,activeCount()可以获得活动线程的总数,但由于线程是动态的,因此这个值只是一个估计值,无法确定精确,list()方法打印这个线程组中所有的线程信息。

有关线程的相关知识(下)相关推荐

  1. 有关线程的相关知识(上)

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/70215452 本文出自:[顾林海的博客] 前言 一系列任务的同时运行称 ...

  2. java线程知识梳理_Java多线程——多线程相关知识的逻辑关系梳理

    1 学习多线程知识的根本目标 多线程知识的根本目标是:设计稳健的并发程序. 当然,本文无法回答这个实践性很强的问题(这与具体的业务相关,涉及到具体的策略),本文主要阐述相关知识之间的关系,希望初学者不 ...

  3. terminated 线程_深入并发,线程相关知识全解析

    一.前言 本文介绍Java线程相关知识(不包括线程同步+线程通信,这个内容在笔者的另一篇博客中介绍过了),包括:线程生命周期.线程优先级.线程礼让.后台线程.联合线程. 二.线程生命周期 2.1 引子 ...

  4. Linux下,进程的相关知识,进程的消耗,常用信息,状态,静态查询命令ps,动态查询命令top

    Linux下,进程的相关知识,进程的来源,去向,状态,静态查询命令ps 一.进程主要组成部分 0.没有执行的程序就是普通文本文件,将程序运行起来以后就是进程,进程又有以下组成部分 1.一个或多个文件 ...

  5. linux怎么打开.o文件,Linux下文件I/O操作的相关知识

    Linux文件I/O主要指的是文件的输入输出,很多初学者对文件的I/O不是很了解,Linux文件I/O的操作较多,下面小编就给大家详细介绍下Linux文件I/O. linux 文件I/O教程(1) 一 ...

  6. 关于外贸的相关知识和经验(下)

    相信许多从事外贸行业的人都已经掌握了很多关于外贸干货的知识累积,例如可以用WhatsApp.intbell和客户保持持续的沟通和联系,可以用google map 寻找客户等等.但很多时候我们积累了很多 ...

  7. 【提高系列】webpack相关知识

    这次我们主要研究的是webpack框架的相关知识,webpack是一个打包构建的前端框架,用于解决前端开发的模块化问题. 应用场景和纵向比较 说到webpack,肯定你还会想到gulp和grunt这些 ...

  8. 后端技术:消息队列MQ/JMS/Kafka相关知识介绍

    ?今天给大家分享消息队列MQ/JMS/Kafka相关知识介绍 1.消息队列介绍 首先举个收快递的栗子,传统的收快递,快递小哥把我们的快递送到我们的手里.他需要什么条件嗯? 快递小哥有时间送, 我们有时 ...

  9. 【Python五篇慢慢弹(5)】类的继承案例解析,python相关知识延伸

    类的继承案例解析,python相关知识延伸 作者:白宁超 2016年10月10日22:36:57 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给 ...

最新文章

  1. 正向最大匹配算法 python代码_中文分词算法之最大正向匹配算法(Python版)
  2. 粽子也内卷?2021 互联网大厂端午礼盒大盘点
  3. 英伟达验证图片加载不出来_让大卫雕塑跳舞、蒙娜丽莎说话,英伟达视频合成有如此多「骚操作」...
  4. 计算机安装双系统后系统引导修复的方法
  5. 2021高考成绩查询系统 www.lzk.hl.cn,2021年黑龙江高考志愿在线填报网址入口:https://www.lzk.hl.cn/...
  6. 最大正方形Python解法
  7. java todo error_运行我的第一个Java应用程序出错
  8. iOS 初识CoreBluetooth
  9. CSS3背景渐变。。。
  10. 苹果锁定计算机的快捷键,苹果电脑快捷键使用 Mac快捷键大全详细介绍
  11. Dorado 7 Ajax 交互处理
  12. 四网协同之WLAN专利分析与启示
  13. github:配置ssh密钥
  14. Bugku—凯撒部长的奖励
  15. Linux下手动安装screen
  16. python数据分析与应用第五章实训 2_第五章实训(二)
  17. python 条形图填充疏密_Python数据分析 4:图表绘制工具Matplotlib
  18. mne-python 安装大法
  19. Redis 无畏宕机快速恢复的杀手锏
  20. 数学之美:深度学习中的概率论

热门文章

  1. status_code想要得到302却得到200_曼联华裔小妖接尤文3.5万周薪合同,签约费200万!意甲要挖空曼联...
  2. python hello world程序编写_编写高质量代码 改善Python程序的91个建议
  3. 软件版本号命名规范_电影录音部门和剪辑部门交互规范的参考
  4. shell 脚本 变量 获取程序输出结果异常分析
  5. 这个冬天,将是共享单车最艰难的时刻
  6. mysql-Mac终端下遇到的问题总结
  7. Qt 5.5增加了新的GL模块,并改进了跨平台支持
  8. 最短路算法总结(入门版)
  9. 宋体节点hdoj 1520 Anniversary party(树形dp)
  10. 网络字节序,主机字节序,地址转换函数