多线程基础(2):Thread 类以及常见的方法,线程的状态

一.Thread 类及常见方法

Thread 类是 JVM 用来管理线程的一个类,换句话说,每个线程都有一个唯一的 Thread 对象与之关联.

每个执行流,也需要有一个对象来描述,Thread 类的对象正是用来描述一个线程执行流的.JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理.

1.对线程重命名

public static void main(String[] args) {
    Thread t1 = new Thread("线程一"){
        @Override
        public void run() {
            while(true){
                try {
                    Thread.sleep(1000);
                    System.out.println("嗨呀!!!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };
    t1.start();
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            while(true){
                try {
                    Thread.sleep(1000);
                    System.out.println("盖亚!!!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    },"线程二");
    t2.start();//新线程启动之后,就把 PCB 挂在链表上

    //主线程
    while(true){
        try {
            Thread.sleep(1000);
            System.out.println("主线程...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上面的两个构造线程的方法,可以通过这两种方式对当前的线程命名.

2.通过控制台查看线程

1)找到 jdk 安装路径的bin目录

在这里插入图片描述

2)直接点击运行,如果不行则需要以管理员的身份运行,选择对应启动的类

在这里插入图片描述

3)查看线程

在这里插入图片描述

3.Thread 的几个常见属性

  • getId():ID 是线程的唯一标识,不同线程不会重复
  • getName():名称是各种调试工具会用到
  • getState(): 状态标识线程当前所处的一个情况
  • getPriority(): 优先级高的线程理论上来说更容易被调度到
  • isDaemon()[是否后台线程]: JVM会在一个进程的所有非后台线程结束后,才会结束运行
  • isAlive():是否存活,即简单的理解为,run方法是否运行结束了
    判定当前内核中的 PCB 是否存在
  • isInterrupted():线程是否被中断

4.中断线程

1)两种中断线程的方式:

目前常见的有以下两种方式:

  • 通过共享的标记来进行沟通
  • 调用 interrupt() 方法来通知

方式一:

private static volatile boolean flag = true;
public static void main(String[] args) {
    Thread t = new Thread("线程一:"){
        @Override
        public void run() {
            while(flag){
                try {
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName()+" 正在工作中...");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("啊?好的,我停止工作了");
        }
    };
    t.start();
    try {
        //3s 后让工作停止
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println(Thread.currentThread().getName()+"(主线程):给我停止工作!");
    flag = false;
}

方式二:

使用 Thread.interrupted() 或者 Thread.currentThread().isInterrupted()代替自定义标志位

Thread 内部包含了一个 boolean 类型的变量作为线程是否被中断的标记

    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
//                while(!Thread.currentThread().isInterrupted()){
                  while(!Thread.interrupted()){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                    System.out.println(Thread.currentThread().getName()+":正在工作中...");
                }
                System.out.println("啊?好的老板");
            }
        },"线程一");
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();//使用这个方法来通知线程结束
        System.out.println(Thread.currentThread().getName()+":该结束工作了");
    }
2)关于interrupt():
3)关于判断线程的标记位

静态的interrupted(): 判断当前线程的中断标志是否设置,调用(通过interrupt()修改标记位)后清除标记位;

非静态的isInterruped():判断对象关联的线程的标志位而是否设置,调用后不清除标志位

public static void main(String[] args) {
    Thread t = new Thread(()->{
        for (int i = 0; i < 10; i++) {
            System.out.println("非静态的标记位调用(修改标记后)后不清除标记:"+Thread.currentThread().isInterrupted());
        }

    });
    t.start();
    t.interrupt();
 }
//得到的结果全为true,因为默认是false,修改后就变成了true了
public static void main(String[] args) {
    Thread t = new Thread(()->{
        for (int i = 0; i < 10; i++) {
            System.out.println("静态的标记位,调用后清楚标记:"+Thread.interrupted());
        }

    });
    t.start();
    t.interrupt();
  
}
//得到的先是true,后边反弹又变回false了
//调用interrupt()方法后,对标记位进行修改,返回true,又改回false了(标记)

5.等待线程join()

Thread.currentThread().join();//即等待这个线程里的任务全都完成,否则一直会阻塞等待

6.获取当前线程的引用

Thread.currentThread();

7.休眠当前线程

Thread.sleep(1000);//单位是ms,也就是等待这个线程1s

二.线程的状态

  • NEW: 对象创建出来了,但是内核的 PCB 还没创建出来
  • RUNNABLE: 可运行的(工作),当前的 PCB 也创建出来了.同时这个 PCB 随时待命(就绪队列).这个线程可能是正在 CPU 上运行,也可能是在就绪队列中排队
  • TIMED_WAITING:表示当前的 PCB 在阻塞队列中等待,这样的等待是一个"带有时间结束"的等待.Thread.sleep(3000);
  • WAITING:线程中如果调用了 wait 方法,也会阻塞等待,此时处在 WAITING 状态.(死等)除非是其他线程唤醒了该线程.
  • BLOCKED: 线程中尝试进行加锁,如果发现锁已经被其他线程占用了.此时该线程也会阻塞等待,这个等待就会在其他线程释放锁之后,被唤醒.
  • TERMINATED: 表示当前 PCB 已经结束了.Thread 对象还在,此时获取状态,得到的就是此状态.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值