线程——Thread类

package threading;

public class Demo7{
    public static void main(String[] args) {

        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"这是我的线程");
        t.start();
    }
}

这是一段用lambda表达式创建的线程。

Thread类的属性

1、ID( getId() )

这是Java中给Thread对象安排的身份标识。和操作系统内核的PCB的pid以及操作系统提供的线程API中的线程id都不是一回事!

一个线程:

1、JVM中有id

2、操作系统的线程API中有id

3、内核PCB中有id

 2、名称( getName() )

在上面用lambda表达式创建的线程中我们能看到,

这个线程我指定name是“这是我的线程”。这一点,在jdk中的jconsole.exe中可以看到

 3、状态( getState() )

操作系统中,状态有两种:就绪和阻塞。而在java中自己有一套状态:

        NEW(初始): Thread 对象创建出来了,但是内核的 PCB 还没创建,(还没有真正创建线程)

        TERMINATED(超时等待): 内核的 PCB 销毁了,但是 Thread 对象还在

        RUNNABLE(运行):就绪状态(正在CPU上运行+在就绪队列中排队)

        TIMED WAITING(超时等待): 按照一定的时间,进行阻塞.sleep

        WAITING(等待): 特殊的阻塞状态. 调用 wait

        BLOCKED(阻塞):等待锁的时候进入的阻塞状态

 4、优先级( getPriority() )

 5、是否为后台线程( isDaemon() )

我们默认创建的线程是前台线程。前台线程会阻止进程退出。所以,如果main运行完了,下前台线程还没完,进程就不会退出!

如果是后台线程就不会阻止进程的退出。

所以,如果main等其他前台线程执行完了,就算有后台线程没执行完,进程也会退出。

package threading;

public class Demo7{
    public static void main(String[] args) {

        Thread t = new Thread(()->{
            while(true){
                System.out.println("hello");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        },"这是我的线程");
        //设置操作得在start之前。如果线程启动了,改不了
        t.setDaemon(true);
        t.start();
        System.out.println("main线程执行结束。");
    }
}

可以看到hello执行了一次就结束了。

 6、是否存活( isAlive() )

线程是否存活 isAlive ——判定内核的线程在不在!
Thread 对象虽然和内核中的中的线程,是一一对应的关系, 但是生命周期并非完全相同。
Thread 对象出来了,内核里的线程还不一定有.调用 start 方法,内核线程才有!

当内核里的线程执行完了(run 运行完了),内核的线程就销毁了.但是 Thread 对象还在。

7、是否被中断( isInterrupted() )

线程的中断实际上是快点将线程结束。而不是运行一半中断。

中断的方法:用标准库里的标志位作为线程是否结束的标记来中断。

package threading;

public class Demo11 {
    public static void main(String[] args) {
        Thread t = new Thread(()->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程执行完了");
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();
        System.out.println("设置t线程结束");
    }
}

Thread.currentThread().isInterrupted()

currentThread()是Thread的静态方法。通过这个方法可以拿到当前线程的实例(Thread对象)

isInterrupted就是判定标志位(为true)

 运行3秒后会发现程序跳出异常后又正常运行。这是因为interrupt有两种情况:

1、t线程在运行状态

        会设置标志位为true。

2、t线程在阻塞状态

        不会设置标志位,而是触发InterruptedException

        这个异常会提前唤醒sleep。

        在上段代码中,异常的处理只是打印日志,且没有结束循环,所以线程会一直执行。

加上bread即可结束循环。

到这,我们能总结出:

        在Java中,中断线程不是强制的。你可以自己处理如何中断线程。

                立即结束:break;

                不理会,线程继续执行:啥都不写

                线程稍后处理:Thread.sleep(1000); break;

        

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值