首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Thread类的方法使用

Thread类的方法使用

作者头像
用户11162265
发布2024-11-20 14:26:38
发布2024-11-20 14:26:38
3630
举报
文章被收录于专栏:C语言C语言

Thread的构造方法

前两种我们在之前的文章中已经讲过了,通过第三、四种我们可以给线程对象命名。

默认情况下,线程对象名字是Thread-N,N是从0开始增加。

Thread的常见属性

start()

start()方法可以开启一个线程,线程创建好后是不会开始执行的,要使用start来开启。

主线程就是main()方法中的线程。

调用start方法后,操作系统层面才会真的创建一个线程。

join()

join()方法可以可以等待一个线程。

join(t)表示等待一个线程t毫秒。

比如在main方法种有两个线程t1、t2,在主线程中有t1.join() ,那么主线程就要阻塞 等待t1线程执行完了才能在执行。如果在t1线程中有t2.join(),那么t1线程就要阻塞 等待t2线程执行完了才能执行任务。

currentThread()

currentThread()方法能获取当前线程对象的引用。

sleep()

Thread.sleep(1000)能让线程休眠1000毫秒,即在这个时间内停止执行任务。

getName()

可以通过getName()方法来获取当前Thread对象的名字

getId()

通过getId()获取Thread对象的编号,这是JVM默认为Thread对象生成的编号,属于Java层面,要与PCB中的PID区分,这是属于操作系统层面的。

getState()

状态:

getState()方法可以获取当前Thread对象的状态,这是Java层面定义的线程状态,要注意和PCB上的区分。

线程有6种状态:NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED。

NEW表示创建好了一个Java线程对象,安排好了任务,只是还没有启动,没有调用start方法之前是不会创建PCB的,和PCB没有关系。

RUNNABLE是运行状态或就绪状态,在操作系统层面已经有了对应的PCB。

BLOCKED是阻塞状态的一种,在等待锁🔒

WAITING表示一直没有时间限制的等待,一直等直到被唤醒。

TIMED_WAITING指定了等待时间的阻塞状态,过时就继续执行任务。

TERMINATED是执行结束,PCB已经销毁,Java层面的线程对象还在。

可以查看Thread对象的所有状态:

代码语言:javascript
复制
public class Demo {
    /**
     * 查看JDK中Thread对象的所有状态
     */
    public static void main(String[] args) {
        //线程状态定义在一个枚举中
        for(Thread.State state: Thread.State.values()){
            System.out.println(state);
        }
    }
}
状态之间的转换:

wait()和notify()是object类中的方法,要搭配使用。

join()、sleep()是Thread类中的方法。

getPriority()

getPriority()能获取线程的优先级,理论上优先级高的更容易被调度到。

isDaemon()

isDaemon()方法能判断线程是否是后台线程。非后台线程即前台线程不会随主线程的结束而结束,而后代线程会随主线程的结束而结束。

创建线程默认是前台的,setDaemon(true)可以将线程设置为后台线程。

JVM会在所有非后台线程都结束了才会结束运行。

代码语言:javascript
复制
public class Demo {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            while(true){
                System.out.println(Thread.currentThread() + "hello");
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        //thread.start();
        System.out.println("线程是否存活:" + thread.isAlive());
        System.out.println("线程是否为后台线程 "+ thread.isDaemon());

        //将线程设置为后台线程
        thread.setDaemon(true);

        thread.start();

        System.out.println("线程是否存活:" + thread.isAlive());
        System.out.println("线程是否为后台线程 "+ thread.isDaemon());

        int i = 0;
        while(i < 2){
            i++;
            Thread.sleep(1000);
            System.out.println("main()主线程没有结束……");
        }
        Thread.sleep(1000);
        System.out.println("结束main()主线程");
    }
}

可以看到设置成后台线程之后,main方法结束后子线程也随之结束了。

前台线程可以阻止进程的退出,后台线程不能阻止进程的退出。

isAlive()

isAlive()方法能判断线程是否存活,如果线程还没开启或者任务执行完成,则线程死了。

描述的是PCB的状态,能判断出run()方法是否执行完成。

代码语言:javascript
复制
 public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            for(int i = 0; i < 5; i++){
                System.out.println("hello thread...");
                try{
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
            }
            System.out.println("线程任务完成。");
        });

        System.out.println("启动之前查看线程是否存活:" + thread.isAlive());
        thread.start();
        System.out.println("启动之后查看线程是否存活:" + thread.isAlive());
        thread.join();
        Thread.sleep(1000);
        System.out.println("线程结束之后查看线程是否存活:" + thread.isAlive());   
 }

isInterrupted()

isInterrupted()判断线程的中断状态。

两种中断方式:

1、自定义标识位,通过修改标识位来通知线程中断

代码语言:javascript
复制
public class Demo_207 {
    private static boolean isQuit = false;
    public static void main(String[] args) throws InterruptedException{
        Thread thread = new Thread(()->{
            while(!isQuit){
                System.out.println(Thread.currentThread().getName() + "hello");
            }
            System.out.println("线程结束咯");
        });
        System.out.println("线程是否存活:" + thread.isAlive());
        System.out.println("线程状态:" + thread.getState());
        System.out.println("线程是否中断:" + thread.isInterrupted());
        thread.start();
       
        isQuit = true;
        //等待线程销毁
        Thread.sleep(100);
        System.out.println("线程是否存活:" + thread.isAlive());
        System.out.println("线程状态:" + thread.getState());
        System.out.println("线程是否中断:" + thread.isInterrupted());
    }
}

注意在lambda表达式中如果使用局部变量会触发“变量捕获”,所以我们需要把变量定义为全局的。

2、通过interrupt()来通知线程中断

代码语言:javascript
复制
public class Demo_208 {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            while(!Thread.currentThread().isInterrupted()){
                System.out.println("hello Thread~");
                try{
                    //休眠时间1s,休眠时间远大于执行任务的时间,所以线程大部分时间都在sleep
                    //sleep时被中断会触发异常,要处理中断逻辑
                    Thread.sleep(1000);
                }catch(InterruptedException e){
                    //处理中断逻辑
                    e.printStackTrace();
                    System.out.println("休眠被中断啦!");
                    break;
                }
            }
            System.out.println("线程退出……");
        });
        System.out.println("线程是否存活:" + thread.isAlive());
        // 启动线程
        thread.start();
        // 主线程休眠一会
        Thread.sleep(1000);
        System.out.println("线程是否存活:" + thread.isAlive());
        // 中断线程,发出中断信号
        thread.interrupt();
        // 等待线程销毁
        Thread.sleep(100);
        // 查看是否存活
        System.out.println("线程是否存活:" + thread.isAlive());
    }
}

当线程处于休眠状态、等待状态时被中断,就会出现这个异常,我们需要在catch语句中处理中断逻辑。

如果线程是在正常运行状态下被中断,不会出现这个异常,直接中断线程。


一个简单代码示例展示使用以上方法:

代码语言:javascript
复制
public class Demo{
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(() -> {
           for(int i = 0; i < 10; i++){
               System.out.println(Thread.currentThread().getName() + " 还活着哟");
               try{
                   Thread.sleep(1000);
               }catch(InterruptedException e){
                   e.printStackTrace();
               }
           }

            System.out.println(Thread.currentThread().getName() + " 我将死去");
        },"kiku线程");


        System.out.println(thread.getName() + " ID:" + thread.getId());
        System.out.println(thread.getName() + " 名称:" + thread.getName());
        System.out.println(thread.getName() + " 状态:" + thread.getState());
        System.out.println(thread.getName() + " 优先级:" + thread.getPriority());
        System.out.println(thread.getName() + " 后台线程:" + thread.isDaemon());
        System.out.println(thread.getName() + " 是否活着:" + thread.isAlive());
        System.out.println(thread.getName() + " 是否被中断:" + thread.isInterrupted());

        //启动线程
        thread.start();

        System.out.println(thread.getName() + " ID:" + thread.getId());
        System.out.println(thread.getName() + " 名称:" + thread.getName());
        System.out.println(thread.getName() + " 状态:" + thread.getState());
        System.out.println(thread.getName() + " 优先级:" + thread.getPriority());
        System.out.println(thread.getName() + " 后台线程:" + thread.isDaemon());
        System.out.println(thread.getName() + " 是否活着:" + thread.isAlive());
        System.out.println(thread.getName() + " 是否被中断:" + thread.isInterrupted());

        //主线程等待thread线程执行任务结束
        thread.join();
        System.out.println(thread.getName() + " ID:" + thread.getId());
        System.out.println(thread.getName() + " 名称:" + thread.getName());
        System.out.println(thread.getName() + " 状态:" + thread.getState());
        System.out.println(thread.getName() + " 优先级:" + thread.getPriority());
        System.out.println(thread.getName() + " 后台线程:" + thread.isDaemon());
        System.out.println(thread.getName() + " 是否活着:" + thread.isAlive());
        System.out.println(thread.getName() + " 是否被中断:" + thread.isInterrupted());
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Thread的构造方法
  • Thread的常见属性
    • start()
    • join()
    • currentThread()
    • sleep()
    • getName()
    • getId()
    • getState()
      • 状态:
      • 状态之间的转换:
    • getPriority()
    • isDaemon()
    • isAlive()
    • isInterrupted()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档