迅速读懂Java线程的交通规则 | 带你学《Java语言高级特性》之八

简介: 线程就像现实世界里复杂的交通线上运行的汽车,有停车让行的,也有一路高歌的,甚至还有特殊情况优先行驶的情况,本节将一一介绍这些内容。

上一篇:教你随心操控线程状态 | 带你学《Java语言高级特性》之七
【本节目标】
通过阅读本节内容,你将学会使用join方法让线程强制一直执行、使用yield方法礼让其他线程优先执行,了解并学会设置线程的优先级使系统自动调度资源执行线程。

线程的强制执行

所谓的线程的强制执行指的是当满足于某些条件之后,某一个线程对象将可以一直独占资源,一直到该线程的程序执行结束。
范例:观察一个没有强制执行的程序

public class ThreadDemo {
   public static void main(String[] args) throws Exception {
       Thread thread = new Thread(() -> {
           for (int x = 0; x < 100; x++) {
               try {
                   Thread.sleep(100);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
               System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
           }
       }, "玩耍的线程");
       thread.start();
       for (int x = 0; x < 100; x++) {
           Thread.sleep(100);
           System.out.println("【霸道的main线程】number = " + x);
       }
   }
}

image.png
图一 没有强制执行的程序

这个时候主线程和子线程都在交替执行着,但是如果说现在希望主线程独占执行,那么就可以用Thread类中的方法:

强制执行 :public final void join(long millis) throws InterruptedException;
public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Thread mainThread = Thread.currentThread();    //获得主线程
        Thread thread = new Thread(() -> {
            for (int x = 0; x < 100; x++) {
                if (x == 3) {      //现在霸道的线程来了
                    try {
                        mainThread.join();    //霸道的线程要先执行
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
            }
        }, "玩耍的线程");
        thread.start();
        for (int x = 0; x < 100; x++) {
            Thread.sleep(100);
            System.out.println("【霸道的main线程】number = " + x);
        }
    }
}

image.png
图二 强制执行

在进行线程强制执行的时候,一定要获取强制执行线程对象之后才可以执行join()的调用。

线程礼让

线程的礼让指的是先将资源让出去让别的线程先执行。线程的礼让可以使用Thread类中提供的方法:

public static void yield();

范例:使用礼让操作

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(() -> {
            for (int x = 0; x < 100; x++) {
                if(x%3==0){
                    Thread.yield();      //线程礼让
                    System.out.println("### 玩耍的线程礼让执行 ###");
                }
                try {
                    Thread.sleep(100);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
            }
        }, "玩耍的线程");
        thread.start();
        for (int x = 0; x < 100; x++) {
            Thread.sleep(100);
            System.out.println("【霸道的main线程】number = " + x);
        }
    }
}

image.png
图三 礼让线程

礼让执行的时候每一次调用yield()方法都只会礼让一次当前的资源。

线程优先级

从理论上来讲,线程的优先级越高,越有可能先执行(越有可能先抢占到资源)。在Thread类中针对优先级的操作提供有如下两个处理方法:

设置优先级:public final void setPriority(int newPriority);
获取优先级:public final int getPriority();

在进行优先级定义的时候都是通过int型的数字来完成的,而对于此数字的选择在Thread类中就定义了三个常量:

最高优先级:public static final int MAX_PRIORITY 、10;
中等优先级:public static final int NORM_PRIORITY 、5;
最低优先级:public static final int MIN_PRIORITY 、1;

范例:观察优先级

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        Runnable run = () -> {
            for (int x = 0; x < 10; x++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "执行。");
            }
        };
        Thread threadA = new Thread(run, "线程对象A");
        Thread threadB = new Thread(run, "线程对象B");
        Thread threadC = new Thread(run, "线程对象C");
        threadA.setPriority(Thread.MIN_PRIORITY);
        threadB.setPriority(Thread.MIN_PRIORITY);
        threadC.setPriority(Thread.MAX_PRIORITY);
        threadA.start();
        threadB.start();
        threadC.start();
    }
}

image.png
图四 线程优先级执行

主方法是一个主线程,那么主线程的优先级呢?默认线程对象的优先级呢?

public class ThreadDemo {
    public static void main(String[] args) throws Exception {
        System.out.println(Thread.currentThread().getPriority());    //5
        System.out.println(new Thread().currentThread().getPriority());    //5
    }
}

主线程属于中等优先级,而默认创建的线程也是中等优先级。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:使用同步解决多人卖票问题 | 带你学《Java语言高级特性》之九
更多Java面向对象编程文章查看此处

相关文章
|
2月前
|
人工智能 安全 Java
智慧工地源码,Java语言开发,微服务架构,支持分布式和集群部署,多端覆盖
智慧工地是“互联网+建筑工地”的创新模式,基于物联网、移动互联网、BIM、大数据、人工智能等技术,实现对施工现场人员、设备、材料、安全等环节的智能化管理。其解决方案涵盖数据大屏、移动APP和PC管理端,采用高性能Java微服务架构,支持分布式与集群部署,结合Redis、消息队列等技术确保系统稳定高效。通过大数据驱动决策、物联网实时监测预警及AI智能视频监控,消除数据孤岛,提升项目可控性与安全性。智慧工地提供专家级远程管理服务,助力施工质量和安全管理升级,同时依托可扩展平台、多端应用和丰富设备接口,满足多样化需求,推动建筑行业数字化转型。
97 5
|
8天前
|
网络协议 安全 Java
实现Java语言的文件断点续传功能的技术方案。
像这样,我们就完成了一项看似高科技、实则亲民的小工程。这样的技术实现不仅具备实用性,也能在面对网络不稳定的挑战时,稳稳地、不失乐趣地完成工作。
23 0
|
7月前
|
监控 Java API
如何使用Java语言快速开发一套智慧工地系统
使用Java开发智慧工地系统,采用Spring Cloud微服务架构和前后端分离设计,结合MySQL、MongoDB数据库及RESTful API,集成人脸识别、视频监控、设备与环境监测等功能模块,运用Spark/Flink处理大数据,ECharts/AntV G2实现数据可视化,确保系统安全与性能,采用敏捷开发模式,提供详尽文档与用户培训,支持云部署与容器化管理,快速构建高效、灵活的智慧工地解决方案。
115 0
|
4月前
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
334 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
3月前
|
存储 Java 数据安全/隐私保护
Java语言位运算符详解
Java语言提供了7种位运算符:按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(&lt;&lt;)、带符号右移(&gt;&gt;)和无符号右移(&gt;&gt;&gt;)。这些运算符主要用于对long、int、short、byte和char类型的数据进行二进制位级别的操作,不能用于double、float和boolean类型。文中详细讲解了每种运算符的规则和应用场景,并指出位运算在实际开发中有重要应用价值,不仅限于面试。
216 2
|
4月前
|
缓存 Java 应用服务中间件
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
725 5
|
3月前
|
Java 开发者
课时2:Java语言特点
课时2介绍了Java语言的多个关键特性。作为开源且半开源的产品,Java成为通用技术标准,拥有透明的开发环境。其面向对象的设计、自动内存回收、简化指针处理(使用引用)、支持多线程编程、高效的网络处理能力(如NIO)及良好的可移植性,共同促成了Java的强大生态系统和广泛应用。
|
5月前
|
存储 监控 算法
探秘局域网桌面监控:深入剖析 Java 语言核心算法
在数字化办公时代,局域网桌面监控如同企业的“智慧鹰眼”,确保工作效率与数据安全。本文以Java为载体,揭示哈希表在监控中的关键应用。通过高效的数据结构和算法,哈希表能快速索引设备连接信息,大幅提升监控的时效性和响应速度。代码示例展示了如何用Java实现设备网络连接监控,结合未来技术如AI、大数据,展望更智能的监控体系,助力企业在数字化浪潮中稳健前行。
|
7月前
|
SQL 安全 Java
安全问题已经成为软件开发中不可忽视的重要议题。对于使用Java语言开发的应用程序来说,安全性更是至关重要
在当今网络环境下,Java应用的安全性至关重要。本文深入探讨了Java安全编程的最佳实践,包括代码审查、输入验证、输出编码、访问控制和加密技术等,帮助开发者构建安全可靠的应用。通过掌握相关技术和工具,开发者可以有效防范安全威胁,确保应用的安全性。
109 4
|
8月前
|
存储 Java API
优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。
【10月更文挑战第19天】本文介绍了如何优雅地使用Java Map,通过掌握其高级特性和技巧,让代码更简洁。内容包括Map的初始化、使用Stream API处理Map、利用merge方法、使用ComputeIfAbsent和ComputeIfPresent,以及Map的默认方法。这些技巧不仅提高了代码的可读性和维护性,还提升了开发效率。
286 3