JavaSE(18)——Thread源码

Thread源码

1. Thread类API

1.1 设置线程名

public class Thread implements Runnable {
    //默认使用的线程名是“Thread-X”
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
    
    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }
}

1.2 守护线程

守护线程是为其他线程服务的:

  • 垃圾回收线程就是守护线程

守护线程有一个特点:

  • 当别的用户线程执行完了,虚拟机就会退出,守护线程也就会被停止掉了
  • 守护线程做为一个服务线程,为由服务对象就没有必要继续运行了

守护线程注意事项:

  1. 线程启动之前设置为守护线程,方法是setDaemon(boolean on)

    如果启动之后再设置会抛出异常

  2. 使用守护线程不要访问共享资源 (数据库、文件等),因为它可能会在任何时候就挂掉了

  3. 守护线程中产生的新线程也是守护线程

1.3 优先级线程

​ 线程优先级高仅仅表示线程获取的CPU时间片的几率高,但这不是一个确定的因素。

​ 线程的优先级是高度依赖于操作系统的,Windows和Linux有区别。Linux下优先级会被忽略

​ Java默认提供的优先级是5,最低是1,最高是10

​ 设置线程优先级时,如果存在线程组,那么该线程的优先级不能高于线程组的优先级。设置了高于线程组的优先级时,会自动的设置为和线程组优先级相同。

setPriority():设置线程优先级

1.4 线程生命周期

​ 线程有3个基本状态:执行、就绪、阻塞

​ Thread中,有很多方法是用来切换线程状态的。

线程状态转换图

  • sleep方法

    调用sleep方法会进入阻塞状态,等时间到了,进入的是就绪状态而非是运行状态。

  • yield方法 (不常用)

    调用yield方法会先让别的线程执行,但是不确保真正让出

  • join方法

    调用join方法,会等待被join线程执行完毕后才执行别的线程

    如:在B线程中,执行A.join,此时B线程会进入阻塞状态(循环调用wait方法),开始执行A,等A执行完,再执行B线程(notify唤醒)。

  • interrupt方法

    在之前的jdk版本中,存在Thread.stop方法,但是被设置为过时了。现在已经没有强制线程终止的方法了。

    stop强制线程终止的策略太暴力且不安全,因此被过时

    在现在的版本中,一般使用Interrupt来请求终止线程

    • Interrupt不会真正停止一个线程,它不仅仅是给这个线程发了一个信号告诉他,它应该要结束了。
    • Java设计者实际上是想让线程自己来进行终止,通过Interrupt发出的信号,可以判断是否需要进行终止业务
    • 具体进行中断还是继续执行,由被通知的线程自己决定
    public void interrupt() {
        if (this != Thread.currentThread())
            checkAccess();
    	//使用了闭锁
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                //只将线程中的Interrupt标记置为true
                interrupt0();           
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }
    

    调用Interrupt并不是真正要终止掉当前线程,仅仅是设置了一个中断标志。这个标志用来判断当前线程的状态,什么时候中断由线程内部决定,这样就可以安全地终止线程了。

    Interrupt方法是不会对线程的状态造成影响的,它仅仅设置一个标志位。

    Interrupt线程中断还有两个方法:

    • 静态方法 interrupted() --> 清除中断标志位
    • 实例方法 isInterrupted() --> 不会清楚中断标志位

    如果阻塞线程调用了interrupt()方法,那么会抛出异常,设置标志位为false,同时该线程会退出阻塞的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值