java基础(多线程)-常用方法具体使用

news2024/10/5 15:24:54

一、Thread.start()方法

start()方法:启动子线程

new Thread();当前线程的状态为NEW

调用start()方法之后当前线程的状态变为RUNNABLE

二、Thread.sleep()静态方法

1. 调用sleep会让当前线程从Running进入Timed Waiting 状态

2.其他线程可以使用interrupt方法打断正在睡眠的线程,这时sleep方法会抛出InterruptedException

3. 睡眠结束后的线程未必会立刻得到执行

4. 建议用TimeUnit的sleep代替Thread的sleep来获得更好的可读性。

总结:在没有利用CPU来计算时,不要让while(true)空转cpu,这时可以使用yield或sleep来让出cpu的使用权给其他程序

  • 可以使用wait或条件变量达到类似的效果
  • 不同的是,后两种都需要加锁,并且需要相应的唤醒操作,一般适用于要进行同步的场景
  • sleep适用于无需锁同步的场景

三、yield()

1. 调用yield会让当前线程从Running进入Runnable就绪状态,然后调度执行其他线程

2. 具体的实现依赖于操作系统的任务调度器。

四、线程优先级setPriority

  • 线程优先级会提示调度器优先调度该线程,但它仅仅是提示,调度器可以忽略它
  • 如果cpu比较忙,那么优先级高的线程会获得更多的时间片,但cpu闲时,优先级几乎没作用。

五、join() 等待线程结束

  • 需要等待结果返回,才能继续运行就是同步
  • 不需要等待结果返回,就能继续运行就是异步

六、interrupt()方法

interrupt打断sleep,wait,join的线程。叫醒线程。

七、两阶段终止模式

如何终止一个线程
终止一个线程早期Thread是提供对应的停止方法的,比如stop等,但是到后来停止一个线程的api都已经过时了,即存在风险,不推荐使用,那如果碰到这种线程停止的需求如何实现, 且是优雅的实现, 那么两个阶段终止模式就可以实现。它的意思就是, 第一阶段时准备停止阶段,第二阶段是停止阶段。思路就是 B线提供一个一个标志,如果别的线程把这个标志设计为true,那么当前线程就终止。


 

class TwoPhaseTermination{
    Logger logger =LoggerFactory.getLogger(TwoPhaseTermination.class);
    private Thread monitor;
    //启动监控线程
    public void start(){
        monitor = new Thread(()->{
            while (true){
                Thread current = Thread.currentThread();
                if(current.isInterrupted()){
                    logger.info("料理后事");
                    break;
                }
                try {
                    Thread.sleep(1000);
                    logger.info("执行监控记录");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //重新设置打断标记
                    monitor.interrupt();
                }
            }
        });
        monitor.start();
    }

    public void stop(){
        monitor.interrupt();
    }
}

八、不推荐使用方法

还有一些不推荐使用的方法,这些方法已过时,容易破坏同步代码块,造成线程死锁

方法名static功能说明
stop()停止线程运行
suspend()挂起(暂停)线程运行
resume()回复线程运行

九、主线程与守护线程

默认情况下,Java进程需要等待所有线程都运行结束,才会结束。有一种特殊的线程叫做守护线程,只要其他非守护线程运行结束了,即使守护线程的代码没有执行完,也会强制结束。

    public void testDaemon() throws InterruptedException {
        logger.info("开始运行...");
        Thread t1 = new Thread(() -> {
            logger.info("开始运行...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            logger.info("运行结束...");
        },"daemon");
        //设置该线程为守护线程
        t1.setDaemon(true);
        t1.start();
        Thread.sleep(1000);
        logger.info("运行结束...");
    }
  • 垃圾回收器线程就是一种守护线程
  • Tomcat中的Acceptor和Poller线程都是守护线程,所以Tomcat接收到shutdown命令后,不会等待他们处理完当前请求。

十、线程的五种状态

从操作系统层面来描述,线程有五种状态

【初始状态】:仅是在语言层面创建了线程对象,还未与操作系统线程关联

【可运行状态】:(就绪状态)指该线程已经被创建(与操作系统线程关联),可以由CPU调度执行

【运行状态】:指获取了CPU时间片运行中的状态

  • 当CPU时间片用完,会从【运行状态】转换至【可运行状态】 ,会导致线程的上下文切换。

【阻塞状态】:

  • 如果调用了阻塞API,如BIO读写文件,这时该线程实际不会用到CPU,会导致线程上下文切换,进入【阻塞状态】
  • 等BIO操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
  • 与【可运行状态】的区别是,对【阻塞状态】的线程来说,只要他们一直不唤醒,调度器就一直不会考虑调度他们。

【终止状态】:表示线程已经执行完毕,生命周期已经结束,不会再转换为其他状态。

十一、线程的六种状态

六种状态是从Java API层面来描述,根据Thread.state枚举,分为六种状态。

 【NEW】:线程刚被创建,但是还没有调用start()方法

【RUNNABLE】:当调用了start()方法之后,注意Java API层面的RUNNABLE状态涵盖了操作系统层面的【可运行状态】、【运行状态】和【阻塞状态】(由于BIO导致的线程阻塞,在java里无法区分,仍然认为是可运行)

【BLOCKED、WAITING、TIMED_WAITING】三种状态都是java api层面对【阻塞状态】的戏份,后面会在状态转换一节详细讲述。

【TERMINATED】:当线程代码运行结束

public void testThreadState() throws InterruptedException {
        Thread t1 = new Thread("t1"){
            @Override
            public void run(){
               logger.info("running...");
            }
        };

        Thread t2 = new Thread("t2"){
            @Override
            public void run(){
                while (true){

                }
            }
        };
        t2.start();


        Thread t3 = new Thread("t3"){
            @Override
            public void run(){
                logger.info("running...");
            }
        };
        t3.start();

        Thread t4 = new Thread("t4"){
            @Override
            public void run(){
                synchronized (ThreadTest.class){
                    try {
                        Thread.sleep(100000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        };
        t4.start();

        Thread t5 = new Thread("t5"){
            @Override
            public void run(){
                try {
                    t2.join();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        };
        t5.start();

        Thread t6 = new Thread("t6"){
            @Override
            public void run(){
                synchronized (ThreadTest.class){
                    try {
                        Thread.sleep(100000);
                    }catch (Exception e){
                        e.printStackTrace();
                    }
                }
            }
        };
        t6.start();
        Thread.sleep(500);
        logger.info("t1的状态{}",t1.getState()); //NEW
        logger.info("t2的状态{}",t2.getState()); //RUNNABLE
        logger.info("t3的状态{}",t3.getState()); //TERMINATED
        logger.info("t4的状态{}",t4.getState()); //TIMED_WAITING
        logger.info("t5的状态{}",t5.getState()); //WAITING
        logger.info("t6的状态{}",t6.getState()); //BLOCKED
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642967.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ES6相关概念

什么是ES6? ES 的全称是 ECMAScript , 它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。 为什么使用 ES6 ? 每一次标准的诞生都意味着语言的完善,功能的加强。JavaScript语言本身也有一些令人不满意的地方。 变量提升特性增加了程序运行…

一文讲清超算,高性能计算,并行计算,分布式计算的区别

摘要: 超算、高性能计算、并行计算和分布式计算是计算领域中的重要概念,但它们之间的区别常常令人困惑。本文将为你解析它们的概念与特点,让你在这个领域里轻松游刃有余。 ... ... 超算、高性能计算、并行计算和分布式计算是计算领域中的重要概念&#x…

LVS + Keepalived群集

文章目录 LVS Keepalived1 Keepalived及其工作原理2 一个健康的集群的特点3 Keepalived常见问题脑裂3.1 原因3.2 预防3.3 配置 4 部署keepalived4.1 部署192.168.146.204.2 部署192.168.146.30 5 LVSKeepalived高可用群集5.1 部署192.168.146.50(nginx)5.2 部署192.168.146.60…

在家就能赚钱的方法,我不允许你还不知道

近年来,随着互联网的迅猛发展,具有敏锐嗅觉的人们只需利用互联网,就能愉快地获取收入。一般而言,在线赚钱所需的投资较少,有时只需一台可上网的电脑或手机即可满足,因此有时被称为“零成本或低成本网络赚钱…

Vue学习 之 第一个Vue应用

第一个 Vue 应用 安装WebStorm 在这之前,已下载安装好了WebStorm。 打开WebStorm,点击”“就可以创建一个新的应用。 项目文件目录地址: /Users/morris/WebstormProjects 或者在 file -> new priject 也可以新建一个项目 新建一个 ht…

中小商户如何实现门店数字化运营与管理,有没有好用的工具推荐?

中小商户开展门店数字化运营与管理,能够实现在线支付、退货、换货等快速操作,针对性的精准营销和服务,增加客户忠诚度。 门店数字化运营与管理可以帮助商家建立全面、实时的业务数据管理系统,提高工作效率和客户满意度&#xff0c…

线程池的主要处理流程及常用方法

线程池的主要处理流程及常用方法 更多优秀文章,请扫码关注个人微信公众号或搜索“程序猿小杨”添加。 一、主要处理流程: 当调用线程池execute() 方法添加一个任务时, threadPoolExecutor.execute,具体代码如下: p…

013 - STM32学习笔记 - DMA_存储器到外设

011 - STM32学习笔记 - DMA_存储器到外设 DMA存储器到外设 上节学习了DMA的存储器到存储器,这节了解一下存储器到外设,以存储器到USART1为例,DMA的配置函数M2P_DMA_Config流程跟上节的基本一致,区别在于需要选择DMA的通道和数据…

企业成本发票不足,利润虚高,此类问题该如何解决?

《税筹顾问》专注于园区招商,您的贴身节税小能手,合理合规节税! 企业利润很高的情况下,缺成本发票的问题又很严重,那么需要缴纳的企业所得税就会高的吓人了,那么企业利润很容易就超过300万,这样…

汉明码(Hamming Code)底层原理

汉明码(Hamming Code)底层原理 3Blue1Brown:Hamming Code【Part1】 3Blue1Brown:Hamming Code【Part2】 Hamming Code如何检查错误和定位错误? 检查错误通过奇校验或偶校验确定是否发生错误 定位错误通过依次对行和列…

2023ISCC web wp

文章目录 1.羊了个羊2.小周的密码锁3.老狼老狼几点了4.ISCC疯狂购物节-15.ChatGGG6.Where_is_your_love7.ISCC内部零元购-28.ISCC单身节抽奖9.上大号说话10.ISCC滥用职权-3 1.羊了个羊 在url前缀加上view-source:来查看源码,在vue.global.js中发现可疑字符串。 两次…

这个数据机构是二叉树

文章目录 前言一、二叉树的链式存储二、二叉树链式结构的实现二叉树的结构设计手动构建二叉树二叉树的前序遍历二叉树的中序遍历二叉树的后序遍历二叉树的层序遍历计算二叉树大小计算叶子节点个数计算二叉树高度计算第K层的节点个数查找某个值对应的节点二叉树的销毁 三、完整代…

2.7 协程设计原理

目录 一、为什么要有协程?二、协程的原语操作1、基本操作2、让出(yield)和恢复(resume) 三、协程的切换(switch)1、汇编2、ucontext3、longjmp / setjmp 四、协程结构的定义五、协程调度器结构的…

【C++】string类的深入介绍

【C】string类的深入介绍(1) 目录 【C】string类的深入介绍(1)标准库中的string类string类(了解即可)string类的常用接口说明(最常用的)详细介绍string::operator[] 迭代器string中的…

AI时代来临!使用ChatGPT和Kapa.ai协助学习成长!

在加密领域畅游时,常常会遇到不懂的技术名词或是其背后代表的含义,此时通常都需要花费大量的时间进行研究和学习方能掌握。但是自从ChatGPT人工智能的出现,通过简单有效地运用其特性,不仅可以大大提高研究的效率,还可以…

统信UOS V20 安装mysql5.7.42详细教程

1 安装包准备 到mysql官网可以看到最新的是8.0.33,想下载其他版本的点击 Looking for previous GA versions?Select Operating System: 选择如下版本的mysql 安装包 2 安装 2.1 上传文件至服务器 下载后通过远程将安装包上传至服务器,我这里将安装…

软件测试在不同应用场景中,我们该如何进行测试呢?

在我们的日常工作中,我们通常接触到的都是比较复杂的系统。而复杂的系统就意味着比较复杂的测试程序。首先,对于复杂的系统来说,如果想要做功能测试,一般需要考虑到测试数据的问题,还要考虑如何从全局出发,…

canal 环境搭建和配置

canal 环境搭建和配置 安装依赖环境 安装canal服务端 canal客户端配置 安装依赖环境 下载Linux版jdk 链接:百度网盘 请输入提取码 提取码:5r2e --来自百度网盘超级会员V5的分享上传到 /soft/java目录下,并解压-执行如下命令 tar -zxvf jdk…

基于Java在线医疗服务系统设计与实现(源码+lw+部署文档+讲解等)

博主介绍: ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ 🍅 文末获取源码联系 🍅 👇🏻 精…

Media3:Android下一代媒体框架

无论您是在构建音乐播放器、视频流应用程序还是其他需要播放媒体内容的 Android 应用程序,拥有可靠的媒体播放库都是必不可少的。 这就是 Media3 发挥作用的地方。 什么是 Media3? Media3 是由 Google 作为 AndroidX 的一部分推出的强大媒体播放库。它…