一篇文章掌握Java Thread的类及其常见方法

 更新时间:2022年03月02日 14:56:01   作者:/少司命  
Thread类用于操作线程,是所以涉及到线程操作(如并发)的基础。本文将通过代码对Thread类的功能作用及其常见方法进行分析

一,Thread 的几个常见属性

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

Java中创建线程

显示继承Thread,重写run方法来指定线程执行的代码

匿名内部类来继承Thread,重写run方法来指定线程执行的代码

显示实现Runnable接口,重写run方法

匿名内部类来继承Runnable接口,重写run方法

通过lambda表达式来描述执行的代码

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

ID 是线程的唯一标识,不同线程不会重复

名称是各种调试工具用到 状态表示线程当前所处的一个情况,下面我们会进一步说明

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

关于后台线程,需要记住一点:JVM会在一个进程的所有非后台线程结束后,才会结束运行。

是否存活,即简单的理解,为 run 方法是否运行结束了

线程的中断问题,下面我们进一步说明

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread("123"){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.currentThread().getName());
                    try{
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("线程退出");
            }
        };
 
        //这一组属性,线程创建完成后,属性就不变了
        System.out.println(t.getName());
        System.out.println(t.getPriority());
        System.out.println(t.isDaemon());
        System.out.println(t.getId());
        //这组属性会随着线程的运行而开始改变
        System.out.println(t.isAlive());
        System.out.println(t.isInterrupted());
        System.out.println(t.getState());
 
        t.start();
 
        while (t.isAlive()){
            System.out.println("123 正在运行");
            System.out.println(t.getState());
            System.out.println(t.isInterrupted());
            Thread.sleep(300);
        }
    }

二,线程调试

1,启动一个线程

之前我们已经看到了如何通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。

覆写 run 方法是提供给线程要做的事情的指令清单

线程对象可以认为是把 李四、王五叫过来了

而调用 start() 方法,就是喊一声:”行动起来!“,线程才真正独立去执行了。

 static class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("我是一个线程");
        }
    }
 
    public static void main(String[] args) {
        Thread t = new MyThread();
        t.start();
    }

2,中断一个线程

中断让一个程序结束,结束可能有两种情况

        1,已经把任务执行完了

        2,任务执行到一半,被强制结束

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
               while (! isQuit){
                   System.out.println("正在转账");
                   try {
                       Thread.sleep(500);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
                System.out.println("转账终止");
            }
        };
        t.start();
        Thread.sleep(500);
        System.out.println("有内鬼,终止交易");
        isQuit = true;
    
}

public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            @Override
            public void run() {
                while (!Thread.interrupted()){
                    System.out.println("正在转账");
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        break;
                    }
                }
                System.out.println("转账终止");
            }
        };
        t.start();
        Thread.sleep(5000);
        System.out.println("有内鬼,终止交易");
        t.interrupt();
    }

thread 收到通知的方式有两种:

1. 如果线程因为调用 wait/join/sleep 等方法而阻塞挂起,则以 InterruptedException 异常的形式通 知,清除中断标志

        当出现 InterruptedException 的时候, 要不要结束线程取决于 catch 中代码的写法. 可以选择 忽略这个异常, 也可以跳出循环结束线程.

2.否则,只是内部的一个中断标志被设置,thread 可以通过

        Thread.interrupted() 判断当前线程的中断标志被设置,清除中断标志

        Thread.currentThread().isInterrupted() 判断指定线程的中断标志被设置,不清除中断标志

这种方式通知收到的更及时,即使线程正在 sleep 也可以马上收到。

public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.interrupted());
                }
            }
        };
        t.start();
        t.interrupt();
    }

public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println(Thread.currentThread().isInterrupted());
                }
            }
        };
        t.start();
        t.interrupt();
    }

3,等待一个线程

t1与t2串行执行

 public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println("我是线程1");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
 
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
               for (int i = 0; i < 10; i++){
                   System.out.println("我是线程2");
                   try {
                       Thread.sleep(50);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        };
 
 
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("主线程执行完毕");
    }

t1与t2并发执行

public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 10; i++){
                    System.out.println("我是线程1");
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        };
 
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
               for (int i = 0; i < 10; i++){
                   System.out.println("我是线程2");
                   try {
                       Thread.sleep(50);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            }
        };
 
 
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println("主线程执行完毕");
    }

4,休眠线程

public static void main(String[] args) throws InterruptedException {
        System.out.println(System.currentTimeMillis());
        Thread.sleep(1000);
        System.out.println(System.currentTimeMillis());
    }

1,如果线程在正常运行计算判断逻辑,此时就是在就绪队列中排队,调度器就会从就绪队列中筛选出合适的PCB让他在CPU上运行

2,如果某个线程调用sleep就会让对应的线程的PCB进入阻塞队列,阻塞队列无法在PCB上运行

3,时间到了之后,就自动把这个PCB拿回到原来的就绪队列中

到此这篇关于一篇文章掌握Java Thread的类及其常见方法的文章就介绍到这了,更多相关Java Thread内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JDBC PreparedStatement Like参数报错解决方案

    JDBC PreparedStatement Like参数报错解决方案

    这篇文章主要介绍了JDBC PreparedStatement Like参数报错解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • 如何基于Spring使用工厂模式实现程序解耦

    如何基于Spring使用工厂模式实现程序解耦

    这篇文章主要介绍了如何基于Spring使用工厂模式实现程序解耦,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 基于FlashPaper实现JSP在线阅读代码示例

    基于FlashPaper实现JSP在线阅读代码示例

    这篇文章主要介绍了基于FlashPaper实现JSP在线阅读代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • IDEA项目使用SpringBoot+MyBatis-Plus的方法

    IDEA项目使用SpringBoot+MyBatis-Plus的方法

    这篇文章主要介绍了IDEA项目使用SpringBoot+MyBatis-Plus的方法,本文分步骤通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • IDEA使用GsonFormat完成JSON和JavaBean之间的转换

    IDEA使用GsonFormat完成JSON和JavaBean之间的转换

    这篇文章主要介绍了IDEA使用GsonFormat完成JSON和JavaBean之间的转换,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • Java利用Zxing生成二维码的简单实例

    Java利用Zxing生成二维码的简单实例

    下面小编就为大家带来一篇Java利用Zxing生成二维码的简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • IDEA Error:java: 无效的源发行版: 17错误

    IDEA Error:java: 无效的源发行版: 17错误

    本文主要介绍了IDEA Error:java: 无效的源发行版: 17错误,这个错误是因为您的IDEA编译器不支持Java 17版本,您需要更新您的IDEA编译器或者将您的Java版本降级到IDEA支持的版本,本文就来详细的介绍一下
    2023-08-08
  • java.Net.UnknownHostException异常处理问题解决

    java.Net.UnknownHostException异常处理问题解决

    这篇文章主要介绍了java.Net.UnknownHostException异常处理方法,问题原因是在系统的 /etc/Hostname中配置了主机名,而在/etc/hosts文件中没有相应的配置,本文给大家详细讲解,需要的朋友可以参考下
    2023-03-03
  • Java中System.currentTimeMillis()计算方式与时间单位转换讲解

    Java中System.currentTimeMillis()计算方式与时间单位转换讲解

    本文详细讲解了Java中System.currentTimeMillis()计算方式与时间单位转换,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • GC参考手册二java中垃圾回收原理解析

    GC参考手册二java中垃圾回收原理解析

    由于有个垃圾回收机制,java中的额对象不在有“作用域”的概念,只有对象的引用才有“作用域”。垃圾回收可以有效的防止内存泄露,有效的使用空闲的内存<BR>
    2022-01-01

最新评论