黑马程序员——java语言基础——线程学习笔记二

本文详细解析Java线程概念,着重探讨守护线程的特点与作用,包括优先级、服务提供、垃圾回收器的典型应用以及如何设置守护线程。同时,介绍线程组的概念与操作方法,展示如何通过线程组统一管理线程,实现中断与销毁多个线程的功能。

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


线程:

守护线程特点:

  • 优先级非常低,通常在程序里没有其他线程运行时才会执行它;
  • 当守护线程是程序里唯一在运行的线程时,JVM会结束守护线程并终止程序;

说明:守护线程通常用于在同一程序里给普通线程(也叫用户线程)提供服务,它们可能随时被终止。JAVA中最典型的这种类型代表就是垃圾回收器。

用户线程特点:

  • 用户线程会运行到非守护线程的所有线程都已停止运行为止或者调用了 Runtime 类的 exit 方法,并且安全管理器允许退出操作发生为止。

注意:

1、每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程。

2、每个线程都可以或不可以标记为一个守护程序。

3、当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序,例如当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法),那么我们在main方法中创建的线程就是非守护线程,除非该新创建的线程在运行之前设置为守护线程。同样的,如果线程是守护线程,那么在线程执行代码中创建的线程也是守护线程。


设置守护线程或用户线程方法:

public final void setDaemon(boolean on)将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。该方法必须在启动线程前调用,即在构造方法中设置守护属性。该方法首先调用该线程的 checkAccess 方法,且不带任何参数。这可能抛出 SecurityException(在当前线程中)。参数:on - 如果为 true,则将该线程标记为守护线程。

判断线程是否是守护线程的方法:

public final boolean isDaemon()测试该线程是否为守护线程。

守护线程参考代码:

import java.util.Date;

//守护线程类
class ThreadProtected extends Thread {
	
	ThreadProtected() {
		setDaemon(true);//设置守护线程
		
	}
	public void run() {				
		while(true){//守护线程中一般是死循环,并且在所有的非守护线程结束之后会自动结束
			System.out.println("每10秒清理一次");
	}
 }
}
class ThreadNeedProtect implements Runnable {//被守护的线程
    Date date = null; 
	
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		int i = 1;
		for( i = 1; i <= 24 ; i++) {				
				try {
					Thread.sleep(3);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}				
			}				
		}	
}

public class ProtectThreadTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stu		
     ThreadProtected tp = new ThreadProtected();//守护线程
     ThreadNeedProtect tnp = new ThreadNeedProtect();//非守护线程
     System.out.println("tp="+tp.isDaemon());
     tp.start();
     new Thread(tnp).start();    
		
	}

}


ThreadGroup类

    ThreadGroup类继承自Object,实现接口Thread.UncaughtExceptionHandler。而Thread类继承自Object,实现接口Runnable。

    线程组表示一个线程的集合。此外,线程组也可以包含其他线程组。线程组构成一棵树,在树中,除了初始线程组外,每个线程组都有一个父线程组。允许线程访问有关自己的线程组的信息,但是不允许它访问有关其线程组的父线程组或其他任何线程组的信息。

         既然线程组表示的是线程的集合,而且,线程组可以包含其他线程组,那么获取的方法则是:

  • public int activeCount()返回此线程组中活动线程的估计数。结果并不能反映并发活动,并且可能受某些系统线程的存在状态的影响。由于结果所固有的不精确特性,建议只将此方法用于信息目的。
  • public int activeGroupCount()返回此线程组中活动线程组的估计数。结果并不能反映并发活动。由于结果所固有的不精确特性,建议只将此方法用于信息目的。
  • public final ThreadGroup getParent()返回此线程组的父线程组。首先,如果父线程组不为 null,则不使用任何参数直接调用父线程组的 checkAccess 方法;这可能导致一个安全性异常。返回:线程组的父线程组。顶级线程组仅为那些父线程组为 null 的线程组。
         线程组是一个集合,那么关于线程组的复制操作:
  • int enumerate(Thread[] list) 把此线程组及其子组中的所有活动线程复制到指定数组中。
  • int enumerate(Thread[] list, boolean recurse) 把此线程组中的所有活动线程复制到指定数组中。
  • int enumerate(ThreadGroup[] list) 把对此线程组中的所有活动子组的引用复制到指定数组中。
  • int enumerate(ThreadGroup[] list, boolean recurse) 把对此线程组中的所有活动子组的引用复制到指定数组中。
         将线程放入到一个线程组中,就可以利用线程组的方法统一的中断所有的线程,也可以销毁所有的线程,如方法:
  • public final void interrupt()中断此线程组中的所有线程。首先,不使用任何参数调用此线程组的 checkAccess 方法;这可能导致一个安全性异常。然后,此方法将对此线程组及其所有子组中的所有线程调用 interrupt 方法。
  • public final void destroy()销毁此线程组及其所有子组。此线程组必须为空,指示此线程组中的所有线程都已停止执行。首先,不使用任何参数调用此线程组的 checkAccess 方法;这可能导致一个安全性异常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值