【JavaEE】Thread的方法和属性


1、Thread的常见构造方法

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

前面两个构造方法我们在线程的概念这篇中已经讲过了,这里就不在过多赘述
创建线程对象,并命名和使用Runnable对象创建对象,并命名
举例:

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的几个常见属性

属性获取方法
IDgetId()
名称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方法把线程设置为后台线程
举例:

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先执行一次打印(线程之间是抢占式执行,调度顺序不确定)
判断是否为后台线程:

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的生命周期是不一定完全一样的
举例:

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才会在内核中创建出来
代码如下:

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()方法来响应中断并做出相应的处理,通常是安全的终止线程的执行
举例:

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 **

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

2.try catch

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

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

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.声明抛出的异常

  • 41
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值