操作系统——Thread类的基本用法详解

目录

一、Thread类的介绍

1、定义

2、构造方法

3、常见属性

二、线程创建

1、继承Thread类

2、实现Runnable接口

3、匿名内部类

(1)、匿名内部类创建Thread子类对象

(2)、匿名内部类创建Runnable子类对象

4、使用lambda表达式

注:

三、线程中断

1、手动设置标志位

2、调用 interrupt() 方法

四、线程等待

五、线程休眠

六、获取当前线程实例


一、Thread类的介绍

1、定义

Thread类是JVM 用来管理线程的一个类,每个线程都有一个唯一的 Thread 对象与之关联。每个执行流,都需要有一个对象来描述,而 Thread 类的对象就是用来描述线程执行流的,JVM 会将这些 Thread 对象组织起来,用于线程调度,线程管理。

2、构造方法

方法说明举例
Thread()

创建线程对象

Thread t1 = new Thread();
 
Thread(Runnable target)使用Runnable对象创建线程对象Thread t2 = new Thread(new MyRunnable());
 
Thread(String name)创建线程对象,并命名Thread t3 = new Thread("线程1");
 
Thread(Runnable target,String name)使用Runnable对象创建线程对象,并命名Thread t4 = new Thread(new MyRunnable(), "线程2");
 
Thread(ThreadGroup group,Runnable target)线程可以被用来分组管理,分好的组即为线程组\

3、常见属性

属性获取方法说明

ID

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

二、线程创建

1、继承Thread类

  • 自定义一个类继承Thread类,并在该类中重写run方法。
  • 实例化该类,调用start()方法,创建线程。
class MyThread extends Thread{
    @Override
    public void run(){
        while (true){
            System.out.println("线程1");
        }
    }
}
public class Demo01 {
    public static void main(String[] args) {
        MyThread t=new MyThread();
        t.start();
    }
}

 

2、实现Runnable接口

  • 自定义一个类实现Runnable接口,并在类中实现抽象方法run()。
  • 创建实该类后再将实例化对象作为参数传递到Thread类的构造器中,实例化Thread类的对象,通过Thread类的对象调用start()来创建线程。
class MyRunnable implements Runnable{
    @Override
    public void run(){
        while (true){
            System.out.println("线程2");
        }
    }
}
public class Demo02 {
    public static void main(String[] args) {
        MyRunnable runnable=new MyRunnable();
        Thread t=new Thread(runnable);
        t.start();
    }
}

 

注:相比于继承 Thread 类,可以直接使用 this 表示当前线程对象的引用。实现 Runnable 接口,this 表示的是 MyRunnable 的引用,需要使用 Thread.currentThread()。

3、匿名内部类

(1)、匿名内部类创建Thread子类对象

  • 创建匿名内部类
  • 调用start方法创建线程
public class Demo03 {
    public static void main(String[] args) {
        Thread t=new Thread(){
            @Override
            public void run(){
                while (true){
                    System.out.println("线程3");
            }
        };
        t.start();
        while (true){
            System.out.println("main方法");
        }
    }
}

 

 (2)、匿名内部类创建Runnable子类对象

  • 创建匿名内部类
  • 调用start()方法创建线程
public class demo04 {
    public static void main(String[] args) {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                while (true){
                    System.out.println("线程4");
                }
            }
        });
        t.start();
        while (true){
            System.out.println("main方法");
        }
    }
}

 

4、使用lambda表达式

public class Demo05 {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            while (true){
                System.out.println("线程5");
            }
        });
        t.start();
        while (true){
            System.out.println("main方法");
        }
    }
}

 

注:

      上面我们通过覆写 run 方法创建一个线程对象,但线程对象被创建出来并不意味着线程就开始运行了。覆写 run 方法是提供给线程要做的事情的指令清单,run不会创建新的线程,其是在main线程中执行的。调用 start 方法, 才真的在操作系统的底层创建出一个线程

三、线程中断

1、手动设置标志位

使用自定义的变量来作为标志位。

public class demo01 {
    public static boolean isQuit=false;
    public static void main(String[] args) {
        Thread t=new Thread(()->{
           while (!isQuit){
               System.out.println("hello 线程1");
               try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   throw new RuntimeException(e);
               }
           }
            System.out.println("线程1终止");
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //修改
        isQuit=true;
    }
}

 注:当把isQuit从成员变量改成局部变量时无法正常发挥作用。Java要求变量捕获,捕获的变量必须是final或“实际final”。

2、调用 interrupt() 方法

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

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

方法说明
public void interrupt()中断对象关联的线程,如果线程正在阻塞,则以异常方式通知,
否则设置标志位
public static boolean interrupted()判断当前线程的中断标志位是否设置,调用后清除标志位
public boolean isInterrupted()

判断对象关联的线程的标志位是否设置,调用后不清除标志位

例:

public class demo02 {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            //currentThread是获取到当前线程实例(t)
            //isInterrupted是t对象里自带的一个标志位
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("hello 线程2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException ex) {
                        throw new RuntimeException(ex);
                    }
                    break;
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        //将t内部的标志设置成true
        t.interrupt();
    }
}

interrupt()方法的作用:

  • 设置标志位为true
  • 如果该线程正在阻塞(sleep/join/wait)中,此时会将阻塞状态唤醒并通过抛出异常的方式让sleep立即结束。当sleep被唤醒时,sleep会自动把isInterrupted标志位给清空(true->false),这就导致下次循环仍然可以继续执行。可以在catch语句中增加break来结束循环。

四、线程等待

线程之间是并发执行的,操作系统对于线程的调度是无序的,无法判断两个线程的执行先后顺序。有些时候,我们需要能控制线程之间的顺序,线程等待就是其中一种控制线程执行顺序的手段,此处的等待主要是控制线程结束的先后顺序。

方法说明
public void join()等待线程结束
public void join(long millis)等待线程结束,最多等 millis 毫秒
public void join(long millis, int nanos)同理,但可以更高精度
public class demo03 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            System.out.println("hello 线程3");
        });
        t.start();
        //在main方法中等待t执行完后再执行main方法
        t.join();
        System.out.println("hello main");
    }
}

        上图中我们通过在main方法中调用join()方法让main线程阻塞从而使“线程3”先执行,直到“线程3”执行完毕后main线程才从阻塞中解除继续执行。因此想让哪个线程阻塞,就要在哪个线程里调用join()方法。但当main线程调用join()方法时“线程3”已经结束,此时不再阻塞会立即往下执行。

join()方法分类:

  • 无参join()方法:“死等”直到程序结束。
  • 有参join()方法:指定最大超时时间,如果达到时间上限就不再等待。

五、线程休眠

当代码中的某个线程调用sleep()方法时,这个线程就从就绪队列移至阻塞队列暂时不参与调度等待sleep()时间结束,而当到达sleep()的时间则又会被调度到就绪队列。

方法说明
public static void sleep(long millis) throws InterruptedException休眠当前线程 millis毫秒
public static void sleep(long millis, int nanos) throws
InterruptedException
可以更高精度的休眠
public class Demo06 {
    public static void main(String[] args){
        Thread t=new Thread(()->{
            while (true){
                System.out.println("线程6");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
    }
}

注:因为线程的调度是不可控的,所以sleep()方法只能保证实际休眠时间大于等于参数设置的休眠时间的。

六、获取当前线程实例

可以通过Thread.currentThread()的方式来调用,返回的是线程对象的引用,有时候也可以用this替代。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: Thread是Java中用于创建和管理线程的。它提供了一些方法来控制线程的行为。其中一些方法包括: 1. start()方法:用于启动线程并执行run()方法。通过继承Thread并重写run()方法,可以在start()方法被调用时执行自定义的线程代码。 2. run()方法:是线程的主要执行方法。在run()方法中定义了线程要执行的任务。当start()方法被调用时,run()方法会被自动调用。 3. currentThread()方法:是Thread的一个静态方法,用于返回当前正在执行的线程对象。它可以用来获取当前线程的信息,如线程名称等。 4. sleep()方法:用于使线程暂停执行一段时间。可以通过指定休眠时间来控制线程的执行速度。 5. join()方法:用于等待一个线程的结束。当一个线程调用另一个线程的join()方法时,它会暂停自己的执行,直到被调用的线程执行完毕。 6. interrupt()方法:用于中断一个线程的执行。当一个线程调用另一个线程的interrupt()方法时,被调用的线程会收到一个中断信号,可以根据需要做出相应的处理。 以上是Thread的一些常用方法的详解。通过使用这些方法,可以实现线程的创建、启动、暂停、等待和中断等功能。 #### 引用[.reference_title] - *1* *3* [Java中Thread详解](https://blog.csdn.net/Beyondandzy/article/details/118824388)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Thread 部分常用方法详解](https://blog.csdn.net/weixin_41685207/article/details/108877533)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值