多线程(三)Thread 类及常见方法

一,Thread类的几个属性

在这里插入图片描述

⭐①ID 是线程的唯⼀标识,不同线程不会重复
名称是各种调试工具用到
状态表示线程当前所处的⼀个情况,下⾯我们会进⼀步说明
⭐④优先级高的线程理论上来说更容易被调度到
⑤关于守护线程(后台线程),需要记住⼀点:JVM会在⼀个进程的所有非后台线程结束后,才会结束运行。
是否存活,即简单的理解,为 run 方法是否运行结束了
线程的中断问题

属性:状态 -getState()

  Thread thread = new Thread(() ->{
    
    
            System.out.println("当前线程的状态1" + Thread.currentThread().getState());
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        });
        System.out.println("当前线程的状态2" + thread.getState());
        thread.start();

属性:ID和Name–getId()和getName()

/**
 * 线程属性
 * ID和名称 ;ID一定是不同的,是动态分配的
 * 线程名称手动设置
 */
public class ThreadDemo11 {
    
    
    public static void main(String[] args) {
    
    
        Thread thread = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                Thread t = Thread.currentThread();
                System.out.println("线程ID" + t.getId());
                System.out.println("线程名称" + t.getName() );
            }
        });
        thread.start();
    }
}

属性:优先级-getPriority()

/**
 * 获取优先级
 */
public class ThreadByPriority {
    
    
    public static void main(String[] args) {
    
    
        Thread thread = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                // 得到当前线程,并打印线程的优先级
                Thread thread1 = Thread.currentThread();
                System.out.println("线程优先级1:" + thread1.getPriority());
            }
        });
        System.out.println("线程优先级2:" + thread.getPriority());
        thread.start();
    }
}

属性:是否守护线程-isDaemon()

 //在主线程创建子线程
        Thread t = new Thread(()->{
    
    
            Thread t1 = Thread.currentThread();
            System.out.println(t1.getName() + "是否守护线程" + t1.isDaemon());
            // 创建子线程
            Thread tt1 = new Thread(() -> {
    
    
                Thread cThread2 = Thread.currentThread();
                System.out.println(cThread2.getName() + "——是否守护线程:" + cThread2.isDaemon());
            }, "子线程的子线程1");
            tt1.start();
        },"子线程1");

属性:是否存活-isAlive()

/**
 * 线程是否存活 isAlive() -while循环
 */
public class DaemonThreadAlive {
    
    
    public static void main(String[] args) {
    
    
        Thread t = new Thread(() ->{
    
    
          for(int i=0;i < 10;i++){
    
    
              try {
    
    
                  Thread.sleep(5000);
              } catch (InterruptedException e) {
    
    
                  e.printStackTrace();
              }
          }
            System.out.println("执行完了");
        });
        t.start();
        //判断是否存活
        while(t.isAlive()){
    
    
        }
        System.out.println("确认执行完了");
    }
}

二,启动一个线程-start()

线程对象可以认为是把 李四、王五叫过来了。
调用 start() 方法,就是喊⼀声:”行动起来!“,线程才真正独立去执行了

  Thread thread = new Thread(()->{
    
    
      //业务代码
    Thread thread3 = Thread.currentThread();
    System.out.println("名称" + thread3.getName());
  });
  //启动线程
  thread.start();

三,中断线程的方法

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

1.通过共享的标记来进行沟通

//声明一个自定义标识符
private volatile static boolean flag = false;

/**
 * 自定义标识符终止线程
 */
public class InterruptThread1 {
    
    
    //声明一个自定义标识符
    private volatile static boolean flag = false;
    public static void main(String[] args) {
    
    
        Thread thread = new Thread(() -> {
    
    
            while(!flag){
    
    
                System.out.println("正在转账");
                try {
    
    
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
    
    
                    e.printStackTrace();
                }
            }
            System.out.println("差点误了大事");
        });
        thread.start();
        System.out.println("执行结束");
    }
}

标志位是否清除

标志位是否清除, 就类似于一个开关.
Thread.isInterrupted() 相当于按下开关, 开关自动弹起来了. 这个称为 "清除标志位"
Thread.currentThread().isInterrupted() 相当于按下开关之后, 开关弹不起来, 这个称为**“不清除标志位”.**

2.调用 interrupt() 方法来通知

在这里插入图片描述

//终止线程
thread.interrupt();
System.out.println(“终止交易”);

   thread.start();
   Thread.sleep(1000);

     //终止线程
   thread.interrupt();
   System.out.println("终止交易");
   System.out.println("终止标志位3" + Thread.currentThread().isInterrupted());

3,interrupted和isInterrupted的区别

①interrupted是静态方法,所有程序都可以使用的全局方法,isInterrupted是某个实例的方法
②interrupted在使用完后会重置标识符isInterrupted不会重置

具体分析请看

链接: https://blog.csdn.net/qq_55660421/article/details/123662613.

四,等待一个线程-join()

有时,我们需要等待一个线程完成它的工作后,才能进行自己的下一步工作。例如,李四只有等张三工作成功,才决定是否工作,这时我们需要一个方法明确等待线程的结束
在这里插入图片描述

public class ThreadByJoin {
    
    
    public static void main(String[] args) throws InterruptedException{
    
    
        Thread t1 = new Thread(() -> {
    
    
            // 1.张三开始上班
            System.out.println("1.张三开始上班");
            // 2.张三正在上班
            try {
    
    
                Thread.sleep(10 * 1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            // 3.张三下班
            System.out.println("3.张三下班");
        });
        // 启动程序
        t1.start();
//        while (t1.isAlive()) {
    
    
//        }
        // 等待线程 t1 执行完之后,再执行后面的代码
        t1.join();
        Thread t2 = new Thread(() -> {
    
    
            // 1.李四开始上班
            System.out.println("1.李四开始上班");
            // 2.李四正在上班
            try {
    
    
                Thread.sleep(1000);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
            // 3.李四下班
            System.out.println("3.李四下班");
        });
        t2.start();
    }
}

五,休眠当前线程

休眠线程有两种实现:

使用 sleep 休眠

也是我们比较熟悉一组方法,有一点要记得,因为线程的调度是不可控的,所以,这个方法只能保证实际休眠时间是大于等于参数设置的休眠时间的

在这里插入图片描述

/**
 * 休眠线程
 */
public class ThreadSleep {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        Thread t = new Thread(new Runnable() {
    
    
            @Override
            public void run() {
    
    
                try {
    
    
                    Thread.sleep(10*1000);
                } catch (InterruptedException e) {
    
    
                    System.out.println("我接收到了中止执行的通知");
//                e.printStackTrace();
                }
            }
        });
        t.start();
        //休眠线程
        Thread.sleep(1000);
        System.out.println("终止子线程 thread");
        t.interrupt();//终止线程
    }
}

使用 TimeUnit 休眠

import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 休眠线程
 */
public class ThreadTimeUtil {
    
    
    public static void main(String[] args) throws InterruptedException {
    
    
        System.out.println("主线程开始执行了:" + LocalDateTime.now());
        TimeUnit.SECONDS.sleep(3); // 休眠 3s
        System.out.println("主线程又开始执行了:" + LocalDateTime.now());
    }
}

六,获取当前线程的引用

在这里插入图片描述

public class ThreadDemo {
    
    
  public static void main(String[] args) {
    
    
     Thread thread = Thread.currentThread();
     System.out.println(thread.getName());
  }
}

猜你喜欢

转载自blog.csdn.net/qq_55660421/article/details/123707687