展开菜单
首页 精品内容 本月促销 装机必备 Windows PDF教程 macOS软件 IOS软件 Android AI 专题
全部分类

当前位置:

首页 > 编程开发 > Java中Thread类怎么使用和它的属性是什么

Java中Thread类怎么使用和它的属性是什么

在java中可以进行多线程编程,在java标准库中提供了一个Thread类,来表示线程操作。Thread类可以视为java标准库提供的一组解决多线程编程的一组API.创建好的Thread实例,和操作系统中的线程是一一对应的。操作系统提供了关于线程的API(C语言风格),java在对其进行封装就成Thread类。创建线程方法一:继承Thread类classMyThreadextendsThread{@Overridepublicvoidrun(){//此时只是定义处理一个线程类,在系统中总是还没有创建出新的

本文目录

    在java中可以进行多线程编程,在java标准库中提供了一个Thread类,来表示线程操作。Thread类可以视为java标准库提供的一组解决多线程编程的一组API.

    创建好的Thread实例,和操作系统中的线程是一一对应的。操作系统提供了关于线程的API(C语言风格),java在对其进行封装就成Thread类。

    创建线程

    方法一:继承Thread类

    class MyThread extends Thread{
        @Override
        public void run() {
            //此时只是定义处理一个线程类,在系统中总是还没有创建出 新的线程。
            System.out.println("hello thread");
        }
    }
    public class TestDemo11 {
        public static void main(String[] args) {
            //创建线程
            Thread t = new MyThread();
            //启动线程,在系统中创建出了新的线程
            t.start();
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    线程之间是并发执行的

    class MyThread3 extends Thread{
        @Override
        public void run() { //定义一个线程类
            while (true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public class TestDemo13 {
        public static void main(String[] args) {
            Thread t = new MyThread3();
            t.start();//启动t线程
            while(true){
                System.out.println("hello main");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    Java中Thread类怎么使用和它的属性是什么

    我们可以看到1s当执行一个线程中的代码之后 进入阻塞状态,那么下一秒要唤醒那个线程呢?

    我们可以看到执行出来的两个线程中打印出来的日志的顺序是不确定的。每一轮,1s之后,到底是唤醒thread线程还是唤醒main线程,这是不确定的。(抢占式执行),对于操作系统来说,从宏观上对线程进行调度的顺序是随机的

    此处在说明一下Thread.sleep()方法,sleep()这个方法到了ms级别没有那么精确。当调用这个方法之后,把线程强制处于中阻塞(睡眠状态),但是当阻塞时间结束之后,并不是立即在cup上继续执行该线程,如果Thread.sleep(1000),当通过1s后,阻塞时间结束,但是在1001ms,线程也许不会立即执行。也许操作系统中的cup在忙别的线程。或许该线程在1006ms才执行。

    方法二:实现Runnable接口中的run()方法

    //Runnable其实就是描述一个任务
    //创建一个类,实现Runnable接口,重写Runnable类中的run方法,在run()方法中,描述的是该线程要指向的哪些任务。
    class MyThread2 implements Runnable{
        @Override
        public void run() {
            System.out.println("hello thread");
        }
    }
    public class TestDemo12 {
        public static void main(String[] args) {
            //创建线程,把创建好的Runnable实例传给Thread实例
            Thread t = new Thread(new MyThread2());
            t.start();
        }
    }

    方法三:利用内部类

    方法三其实是方法一个的翻版,就是把上面的两种代码,改成了匿名内部类。

    public class TestDemo14 {
        public static void main(String[] args) {
            Thread t1 = new MyThread(){
                @Override
                public void run() {
                    System.out.println("hello thread1");
                }
            };
            Thread t2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("hello thread2");
                }
            });
            t1.start();
            t2.start();
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    方法四:使用lambmd表达式

    public class TestDemo15 {
        public static void main(String[] args) {
            //其实就是使用lambad表达式代替Runnable
            Thread t1 = new Thread(()->{
                //()表示无参的run()方法
                System.out.println("hello thread1");
            });
    
        }
    }

    使用线程的好处

    为了更方便的体现出多线程的好处,在这里我们从0开始自增1,一直自增到10_0000_0000,使用串行方法,和并行方法,并且获取他们执行代码的时间,进行比较。

    public class TestDemo16 {
        public static void func1() throws InterruptedException {
            long big = System.currentTimeMillis();
            //串行执行
            Thread t = new Thread(()->{
                long a = 0;
               for(long i = 0;i<10_0000_0000;i++){
                   a++;
               }
            });
            t.start();
            t.join();
            long end = System.currentTimeMillis();
            System.out.println("串行消耗时间:" + (end - big) + "ms");
        }
        public static void func2() throws InterruptedException {
            long big = System.currentTimeMillis();
            Thread t1 = new Thread(()->{
                long b = 0;
            for(long i = 0;i< 10_0000_0000 / 2;i++){
                b++;
            }
            });
            t1.start();
            Thread t2 = new Thread(()->{
                long c = 0;
                for(long i = 0;i<10_0000_0000/ 2;i++){
                    c++;
                }
            });
            t2.start();
            t1.join();
            t2.join();
            long end = System.currentTimeMillis();
            System.out.println("并行执行消耗时间:" + (end - big) + "ms");
        }
        public static void main(String[] args) throws InterruptedException {
            func1();//串行执行
            func2();//并行执行
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    我们可以很明显的看出串行时间要比并行时间长的多,串行时间几乎是并行时间的2倍。

    Java中Thread类怎么使用和它的属性是什么

    Thread类的其他属性和方法

    Thread的常见构造方法

    属性获取方法
    IDgetId()
    名称getName()
    状态getState()
    优先级getPriority()
    是否后台线程isDaemon()
    线程是否存活isAlive()
    线程是否被中断isinterrupted()
    • ID是线程唯一的标识,不同的线程之间不会重复

    • 名称是各种调试工具用到的

    • 状态标识当前线程的一种情况

    • 优先级高的线程,理论上更容易被执行到

    • 是否存活简单理解为run()方法是否执行结束

    给一个线程起名字

    Thread(String name) 这个东西是给thread对象起一个名字,具体起什么名字和线程的执行效率无关,起名字主要依靠于程序员,方便程序员在后期进行调试。

    public class TestDemo17 {
        public static void main(String[] args) {
            //给线程器名字
            Thread t1 = new Thread(()->{
                while(true) {
                    System.out.println("hello thread1");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"thread1");
    
            Thread t2 = new Thread(()->{
                while(true) {
                    System.out.println("hello thread2");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },"thread2");
            t1.start();
            t2.start();
        }
    }

    那么怎样才能看到,我们定义好的线程名字呢?

    注意:当我们要查看线程名字的时候,程序必须要正在执行,否则我们查找不到对应的线程名字。

    Java中Thread类怎么使用和它的属性是什么

    判断一个线程是否存活

    简单的说就是操作系统中我们创建出来的线程是否还存在

    Thread t 的生命周期和操作系统中对应的线程的生命周期并不是完全一致的。

    我们在定义一个线程类后,在调用t.start()方法之前,操作系统中是没有我们创建出来的线程的。在线程类中的run()方法执行完之后,我们在操作系统中创建出来的线程就被销毁了!但是线程t对象还存在。

    • 总而言之,在调用t.start()方法之前,在执行run()方法之后,此时操作系统中是没有我们创建出来的线程的。

    • 在调用t.start()方法之后,在指向run()方法之前,此时操作系统中存在我们创建出来的线程 判断该线程是由是后台线程

    如果一个线程是后台线程,那么这个线程就不会进行进程退出

    如果一个线程是前台线程,那么这个这个线程就会影响到进程的退出。我们以上的代码在创建线程,那些线程都是前台线程,假如现在有前台线程t1,t2, 现在即使main线程执行结束,但是此时还不可以退出线程,必须要将t1,t2线程执行结束之后,整个线程才会结束。

    假如现在有两个线程t1,t2,它们都是后台线程,那么如果现在main线程执行结束,整个进程就执行结束,此时我们会强制停止t1,t2线程。

    public class TestDemo18 {
        public static void main(String[] args) {
            Thread t = new Thread(()->{
                System.out.println("hello thread");
            });
            t.start();
            System.out.println(t.isDaemon());
        }
    }
    //因为我们创建的是一个前台线程,所以返回false

    Thread的其他常见属性

    创建线程

    创建线程:定义出一个线程类,然后启动线程t.start(),其中start()方法决定系统是不是真的创建出线程。

    Java中Thread类怎么使用和它的属性是什么

    线程的中断

    中断线程简单的可以理解成为就是让该线程中的run()方法执行结束。还有一个特殊的就是main线程,如果想要中断main线程,那么就需要把main线程执行完。

    中断线程方法一:设置一个标志位

    public class TestDemo21 {
        public static void main(String[] args) {
            Thread t = new Thread(()->{
               while(!Thread.currentThread().isInterrupted()) {
                   System.out.println("hello thread");
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            });
            //启动t线程
            t.start();
            //在main线程中中断t线程
            //5s之后中断t线程
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t.interrupt();
        }
    }

    运行结果:当t线程中的sout语句被执行5次之后,线程停止。

    上面的这种写法不够严谨,只适用于该场合,如果化作是别的代码场合的话,有可能不会终止线程。

    这里用一种较好的方法,使用Thread类中自带的检查线程是否断开。

    Thread.interrputed() 这是一个静态方法 Thread.currentThread().isinterrupted() 其中Thread.cerrentThread()可以获得线程的引用。

    t.interrupted()用于中断线程

    public class TestDemo21 {
        public static void main(String[] args) {
            Thread t = new Thread(()->{
               while(!Thread.currentThread().isInterrupted()) {
                   System.out.println("hello thread");
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
            });
            //启动t线程
            t.start();
            //在main线程中中断t线程
            //5s之后中断t线程
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t.interrupt();
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    Java中Thread类怎么使用和它的属性是什么

    在我们上边中断线程,判断标志位的时候,我们使用的是第三种方法。设置标志位的时候使用的是第一种方法。

    在我们的日常开发中,经常会用到Thread.currentThread().isInterrupted()来判断标志位,判断该线程是否被中断。

    还有一种方法判断标志位,但是它是一个静态方法,只能判断一个类中只有一个线程的情况下,这个方法就是Thread.isinterrupted()方法。

    Thread.currentThread().isinterrupted()这个方法判断的是Thread的普通成员,每个实例都有一个标志位。

    在我们以后就无脑使用Thread.currentThread().isInterrupted()方法,判断线程是否中断(标志位)

    线程的等待

    在前面我们也介绍到join()方法,这个方法就是让线程与线程之间,有了一定的执行顺序。我们知道在多线程中的调度是随机的,不确定的,多线程的执行靠调度器安排,该调度器的安排是随机的,不规律的。其实线程等待就是一个行之有效的方法,实际上就是控制线程执行的先后顺序。

    public class TestDemo22 { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(()->{ for(int i = 0;i<5;i++){ System.out.println("hello thread"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }); t.start(); t.join();//main线程调用t.join()方法,main线程就处于阻塞状态,当t线程执行完后,唤醒main线程执行后序代码 System.out.println("hello main"); }}

    Java中Thread类怎么使用和它的属性是什么

    获取线程的引用

    使用方法Thread.currentTread()就可以该线程的实例。

    public class TestDemo23 {
        public static void main(String[] args) {
             Thread t = new Thread(){
                 @Override
                 public void run() {
                     //获取当前线程的引用
                     //System.out.println(Thread.currentThread().getName());
                     //因为当前使用的匿名内部类是继承自Thread类,Thread就是该匿名内部类的父类,所以可以通过this得到当前Thread的实例
                     System.out.println(this.getName());
                 }
             };
             t.start();
        }
    }

    Java中Thread类怎么使用和它的属性是什么

    线程的休眠

    其实线程休眠就是调用Thread.sleep()方法。

    回顾之前的学习内容,我们知道我们使用PCB描述一个进程,使用双向链表来组织进程。这种说法是针对一个进程中只有一个线程的情况下。

    那么如果一个进程中有多个线程存在,那么每个线程就有一个PCB,那么每个进程都会有一组PCB,

    PCB上有一个字段为tgroupId,这个id就相当于是进程的id,进程中的每个线程的tgroupId都是相同的。

    那么进程控制块(process contral block)和线程有什么关系呢?

    其实在linux中是不区分进程和线程的,所谓的线程是程序员自己搞出来的,实际上linux只认进程控制块(PCB),实际上线程就相当于一个轻量级进程。

    Java中Thread类怎么使用和它的属性是什么

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    编程开发 Java thread
    相关文章 更多
    精品专题 更多
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    IOS软件

    正软商城iOS软件专区,精选适用于iPhone和iPad的办公、学习、影音、设计、效率及AI应用,提供功能介绍、适用设备、系统要求和正版获取方式等信息。

    AI

    正软商城AI软件专区,汇集AI写作、AI绘画、AI视频、AI办公、AI编程、AI翻译、智能客服和数据分析等人工智能工具,提供功能介绍、适用平台、收费方式及正版购买信息。

    Mac软件 更多
    Aperty macOS版
    Aperty macOS版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw macOS版
    AionClaw macOS版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy macOS版
    Loomy macOS版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirBuddy 3 macOS版
    AirBuddy 3 macOS版

    AirBuddy 3 是面向 macOS 的蓝牙外设增强工具,可集中查看 AirPods、Beats 与苹果设备电量,提供快速连接、播放控制、电量提醒、桌面小组件和多台 Mac 外设接力等功能。

    AirServer macOS版
    AirServer macOS版

    AirServer macOS版可把 Mac 转换为无线投屏接收端,通过 AirPlay 或 Google Cast 接收手机、平板和电脑画面,并支持多设备同时连接、高清镜像及会话录制,适合家庭娱乐、课堂教学、会议演示和应用展示。

    AnyDesk macOS版
    AnyDesk macOS版

    AnyDesk macOS版是一款适用于远程办公、设备维护和客户支持的远程桌面工具,可连接并操作异地计算机,支持文件传输、无人值守访问、会话权限控制及跨平台协作。

    WINDOWS 更多
    讯飞绘文 网页版
    讯飞绘文 网页版

    讯飞绘文网页版是科大讯飞推出的AI图文创作与内容运营工具,覆盖热点选题、文章生成、稿件校对、智能配图、排版发布和数据复盘等环节,适合自媒体创作者及内容团队在线使用。

    Maya(Autodesk Maya) Windows版
    Maya(Autodesk Maya) Windows版

    Autodesk Maya 是面向影视、电视、动画和游戏行业的专业三维制作软件,集多边形与 NURBS 建模、角色绑定、关键帧和动作捕捉动画、Bifrost 特效模拟、材质开发及 Arnold 渲染于一体,

    Aperty Windows版
    Aperty Windows版

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    火山引擎 网页版
    火山引擎 网页版

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    立刻MV 网页版
    立刻MV 网页版

    立刻MV 面向音乐人、内容创作者和品牌团队,帮助用户低成本完成歌曲 MV、歌词视频、AI 分镜、图生视频与最终合成。

    蛙蛙写作 网页版
    蛙蛙写作 网页版

    蛙蛙写作 AI 创作工具,覆盖小说、剧本、文案,一键生成文稿,打通文字转视频全流程,高效解决创作难题。

    讯飞智作 网页版
    讯飞智作 网页版

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    超级简历WonderCV 网页版
    超级简历WonderCV 网页版

    超级简历WonderCV是面向应届生和AI小白的智能求职平台,覆盖简历、面试与职业规划。

    音述AI 网页版
    音述AI 网页版

    音述AI,是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区。

    AionClaw Windows版
    AionClaw Windows版

    AionClaw 是可在桌面端运行的任务型 AI 助手,通过数字专家与技能市场组合办公、创作、数据和开发能力。

    Loomy Windows版
    Loomy Windows版

    Loomy 是科大讯飞推出的桌面 AI 助手,可通过对话、任务与工作目录协助处理办公、内容创作和资料整理。

    AirServer Windows版
    AirServer Windows版

    AirServer Windows版可把电脑变成AirPlay、Google Cast和Miracast无线投屏接收端,适合会议演示、课堂教学及家庭大屏分享。发送设备通常无需另装客户端,并可同时接收和智能排列多个镜像会话。