【JavaEE】Thread的方法和属性

文章目录

  • 1、Thread的常见构造方法
  • 2、Thread的几个常见属性
    • [2.1 ID](#2.1 ID)
    • [2.2 名称](#2.2 名称)
    • [2.3 状态](#2.3 状态)
    • [2.4 优先级](#2.4 优先级)
    • [2.5 是否后台线程](#2.5 是否后台线程)
    • [2.6 是否存活](#2.6 是否存活)
    • [2.7 是否被中断](#2.7 是否被中断)
  • 3.补充说明
    • [3.1 Thread.sleep()的作用](#3.1 Thread.sleep()的作用)
    • [3.2 Thread.sleep()的异常处理方式](#3.2 Thread.sleep()的异常处理方式)

1、Thread的常见构造方法

方法 说明
Thread() 创建线程对象
Thread(Runnable target) 使用Runnable对象创建线程对象
Thread(String name) 创建线程对象,并命名
Thread(Runnable target, String name) 使用Runnable对象创建线程对象,并命名
Thread(ThreadGroup, Runnable target) 线程可以被用来分组管理,分好组即可

前面两个构造方法我们在线程的概念这篇中已经讲过了,这里就不在过多赘述

创建线程对象,并命名和使用Runnable对象创建对象,并命名

举例:

java 复制代码
public class Test6 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            while (true) {
                System.out.println("hello");               
            }
        },"自定义线程");
        thread.start();        
    }
}

这里我们也可以通过jconsole.exe这个应用程序来观察到

注意:这么没有看到main线程不是main线程没有被创建,而是执行太快,已经执行完毕了

最后一个构造方法,在开发中很少用到,这里不再过多讨论

2、Thread的几个常见属性

属性 获取方法
ID getId()
名称 getName()
状态 getState()
优先级 getPriority()
是否后台线程 isDaemon()
是否存活 isAlive()
是否被中断 isInterrupted()

2.1 ID

ID是线程的唯一标识,不同线程不会重复,这里的ID和系统中PCB上的ID是不同的

2.2 名称

名称是各种调试工具用到

2.3 状态

状态表示线程当前所处的一个情况,后续会再次说明

2.4 优先级

优先级高的线程理论上来说更容易被调度

2.5 是否后台线程

线程有前台线程和后台线程
前台线程:这样的线程如果不运行结束,Java进程是一定不会结束的
前台线程可以有多个,多个前台线程,必须最后一个前台线程结束,进程才可以结束
后台线程:这样的线程,即使继续执行,也不能阻止Java进程结束

在Java代码中,main线程是前台线程,程序员创建出来的线程在默认情况下都是前台线程,我们可以通过setDaemon方法把线程设置为后台线程

举例:

java 复制代码
public class Test7 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");                
            }
        });
        //设置为后台线程
        thread.setDaemon(true);
        thread.start();
    }
}

运行结果:

此时,进程中只有main是前台线程,只要main结束,整个进程就结束了,main执行完start立即结束
此时thread还没来得及打印,进程就结束了,里面的线程也就结束了

注意:这里也有一定的概率,出现thread打印一次,然后结束进程的情况,这个就要看main先执行结束,还是thread先执行一次打印(线程之间是抢占式执行,调度顺序不确定)

判断是否为后台线程:

java 复制代码
public class Test7 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                System.out.println("hello thread");                
            }
        });
        //设置为后台线程
        thread.setDaemon(true);
        thread.start();
        //是后台线程返回true,不是返回false
        System.out.println(thread.isDaemon());
    }
}

运行结果:

2.6 是否存活

指的是系统中的线程(PCB)是否存在

Thread对象的生命周期和PCB的生命周期是不一定完全一样的

举例:

java 复制代码
public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("hello thread");           
        });
        //如果PCB存活返回true,不存活返回false       
        System.out.println(thread.isAlive());
    }
}

运行结果:

只有调用thread.start()方法后,才会创建线程,PCB才会在内核中创建出来

代码如下:

java 复制代码
public class Test8 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            System.out.println("hello thread");           
        });
        thread.start();
        System.out.println(thread.isAlive());
    }
}

2.7 是否被中断

在Java中,我们可以通过调用Thread类的interrupt()方法来终止线程,这会向线程发送一个中断信号,线程可以通过检查isInterrupted()方法来响应中断并做出相应的处理,通常是安全的终止线程的执行

举例:

java 复制代码
public class Test11 {
    public static void main(String[] args) {
        Thread thread = new Thread(()->{
            //currentThread()这是一个static方法,能获取到当前线程,获取到thread这个引用
            //isInterrupte()线程内置的标志位 boolean变量 true表示线程终止 false表示线程继续执行
            while(!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();                    
                }
            }
        });
        thread.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //中断thread线程
        thread.interrupt();
    }
}

运行结果:

注意这里,即使将thread线程中断了,但是循环还在继续执行,这个是为什么?
thread.interrupt();这段代码干了两件事:
1.将Thread.currentThread().isInterrupted()的布尔值改变为true
2.立即唤醒sleep(),不在等待

sleep()被唤醒的同时,就会清除刚才的标志位(又改回false),从而导致代码中的循环继续执行,同时catch()方法中的代码也会执行

之所以要改回来就是把控制权交给程序员,让程序员自己在catch()方法中设置,假如要中断thread线程,只需要在catch()方法中写break;就可以中断循环,使thread线程结束

3.补充说明

3.1 Thread.sleep()的作用

sleep()这个方法指睡眠/休眠,就是让线程主动进入"阻塞状态"(PCB上的状态属性),主动放弃去cpu上执行,时间到了,就会解除阻塞状态重新被调度到cpu上执行

3.2 Thread.sleep()的异常处理方式

**在main方法中处理sleep异常的方式有两种:

1.throws **

java 复制代码
public class Test {
    public static void main(String[] args) throws InterruptedException {
        Thread.sleep(1000);
    }
}

2.try catch

java 复制代码
public class Test {
    public static void main(String[] args) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

如果是在线程的run方法中只能用:try catch

java 复制代码
public class Test {
    public static void main(String[] args) {
        Thread thread = new Thread(()-> {
            System.out.println("hello thread");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }
}

这是因为throws也是方法签名的一部分,在run方法重写的时候,就要求方法的签名要一样

method sign ature包含:1.方法的名字

2.方法的参数列表(包含了类型和个数)

3.声明抛出的异常

相关推荐
m0_5719575838 分钟前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
一点媛艺2 小时前
Kotlin函数由易到难
开发语言·python·kotlin
姑苏风2 小时前
《Kotlin实战》-附录
android·开发语言·kotlin
奋斗的小花生3 小时前
c++ 多态性
开发语言·c++
魔道不误砍柴功3 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2343 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨3 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享
老猿讲编程3 小时前
一个例子来说明Ada语言的实时性支持
开发语言·ada
Chrikk4 小时前
Go-性能调优实战案例
开发语言·后端·golang
幼儿园老大*4 小时前
Go的环境搭建以及GoLand安装教程
开发语言·经验分享·后端·golang·go