【多线程与高并发】- 线程基础与状态

news2024/12/24 9:01:42

线程基础与状态

😄生命不息,写作不止
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 一个有梦有戏的人 @怒放吧德德
🌝分享学习心得,欢迎指正,大家一起学习成长!

在这里插入图片描述

文章目录

  • 线程基础与状态
    • 前言
    • 线程的概念
      • 什么是进程?
      • 什么是线程?
      • 在Java线程中是怎样的呢?
    • Java线程的Sleep、Yield、Join方法
      • 1、sleep方法
      • 2、Yield方法
      • 3、Join方法
    • Java的线程状态
      • 线程的不同状态
      • Java线程的状态转化
      • Java线程状态代码
    • 博文推荐

前言

好久没坚持学习了,所以,这次要好好下定决心学习。多线程与高并发不是一天两天就能弄懂的,需要不断的学习、实践,本次笔者将最近学习的内容知识记录下来。多线程也是一项比较重要的内容,虽然CRUD不太会接触到,但是,在一些相关场景可能会有某些问题是由于线程导致的。

线程的概念

要了解线程的概念,就需要知道什么是进程。简单理解就是一个进程中包含了许多个线程。现在就简单介绍,后续若是有对操作系统进行研究的话会慢慢介绍,具体关于线程进程的内容可以去看看王道的操作系统,里面讲述得特别清楚。

什么是进程?

是系统进行资源分配的基本单位,是操作系统结构的基础,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

什么是线程?

所谓线程就是操作系统(OS)能够进行运算调度的最小单位,是一个基本的CPU执行单元,也是执行程序流的最小单元。能够提高OS的并发性能,减小程序在并发执行时所付出的时空开销。线程是进程的一个实体,是被系统独立调度和分派的基本单位。线程本身是不拥有系统资源的,但是它能够使用同属进程的其他线程共享进程所拥有的全部资源。

在Java线程中是怎样的呢?

在Java中,最常见得就是继承Thread类或者实现Runnable接口,再通过run或者start方法去执行线程。
如以下代码,这是一段很简单得代码块,通过继承Thread类,重写run方法来创建线程,并且通过run和start来运行。

public class Thread_demo01 {
    private static class Thread1 extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("Thread1-" + i);
            }
        }
    }

    public static void main(String[] args) {
        new Thread1().run(); // 顺序执行
//        new Thread1().start(); // 线程同时执行
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("main");
        }
    }
}

这两种不同得启动方式,出现得现象也是不同的。

  • 使用run方法启动线程
    在这里插入图片描述
  • 使用start方法启动线程
    在这里插入图片描述
    关于这两种方式启动线程可以看一下下面的流程图。
    在这里插入图片描述
    run方法是会让线程T1先执行完毕之后,再继续执行主线程,而start方法他是同时执行两个线程。

Java线程的Sleep、Yield、Join方法

1、sleep方法

sleep()需要提供一个时间参数(毫秒),会使得线程在一定的时间内被暂停执行,在sleep的过程中,线程是不会释放锁的,只会进入阻塞状态,让出cpu给其他线程去执行。如下代码演示,此处不做锁的探究。

public class T3_Thread_Sleep {
    public static void main(String[] args) {
        Thread t1 = new Thread(new Thread1());
        Thread t2 = new Thread(new Thread2());
        t1.start();
        t2.start();
    }
    static class Thread1 implements Runnable {
        @Override
        public void run() {
            System.out.println("T1 is running");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("T1 is end");
        }
    }

    static class Thread2 implements Runnable {
        @Override
        public void run() {
            System.out.println("T2 is running");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("T2 is end");
        }
    }
}

运行之后在T1线程休眠的时候会让出cpu资源给T2线程,T1线程会睡眠1秒,T2睡眠2秒,最终结果如图
在这里插入图片描述

2、Yield方法

yield()与sleep()都是让线程暂停执行,也是不会释放锁资源。但是yield并不是让进程进入阻塞态,而是回到就绪态,等待重新获取CPU资源。此时,其他的线程有机会获得cpu资源,也有可能在yield方法进入就绪态后立马变成执行态。如以下代码,同样不考虑锁的问题。

public class T4_Thread_Yield {
    static class Thread1 implements Runnable {
        @Override
        public void run() {
            System.out.println("T1 is running");
            Thread.yield();
            System.out.println("T1 is end");
        }
    }
    static class Thread2 implements Runnable {
        @Override
        public void run() {
            System.out.println("T2 is running");
            System.out.println("T2 is end");
        }
    }

    public static void main(String[] args) {
        Thread t1 = new Thread(new Thread1());
        Thread t2 = new Thread(new Thread2());
        t1.start();
        t2.start();
    }
}

经过不同的测试,结果都是不同的。
在这里插入图片描述
在这里插入图片描述

3、Join方法

join()方法是暂停当前线程,调用执行另一个线程,等待join的线程执行完毕后才能够继续执行当前线程。如以下例子,T1,T2同时开始,在T2线程中join了T1,就会导致T1要先执行完毕之后,才会去执行T2。

public class T5_Thread_Join {
    public static void main(String[] args) {
        Thread T1 = new Thread(() -> {
            System.out.println("T1开始");
            for (int i = 0; i < 5; i++) {
                System.out.println("线程T1执行中: " + i);
            }
            System.out.println("T1结束");
        });
        Thread T2 = new Thread(() -> {
            System.out.println("T2开始");
            for (int i = 0; i < 5; i++) {
                System.out.println("线程T2执行中: " + i);
                if (i == 3) {
                    try {
                        T1.join();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }
             }
            System.out.println("T2结束");
        });
        T1.start();
        T2.start();
    }
}

结果如下,不管怎么测试,都会是T2最后执行结束。
在这里插入图片描述

Java的线程状态

线程具有最基本的三态(就绪、运行、阻塞)。线程与进程一样,各线程之间也存着共享资源和互相合作的制约关系,致使线程运行时具有间断性。接下来看一下如图,这是五种状态的转化。
在这里插入图片描述

线程的不同状态

在Java线程中有6中状态,从线程的创建到线程的终止。线程创建为NEW创建态,通过start启动线程,线程内部会从就绪态转成运行态,在Java线程中统称为“运行态”,线程由于被挂起、调用yeild等方法能够使线程从运行态转成就绪态,也能够通过线程的其他方法或者锁阻塞线程,直到时间结束或者是获得锁等,从而回到RUNABLE状态。

  1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。
  2. 运行(RUNNABLE):Java线程中将就绪(Ready)和运行中(Running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(Ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(Running)。
  3. 阻塞(BLOCKED):表示线程阻塞于锁。
  4. 等待(WAITING):进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)。
  5. 超时等待(TIMED_WAITING):该状态不同于WAITING,它可以在指定的时间后自行返回。
  6. 终止(TERMINATED):表示该线程已经执行完毕。

Java线程的状态转化

如线程状态转换图,以下就是Java线程状态的转换流程。线程可以通过实现Runnable接口或者继承Threa类,然后去实例化Java的线程对象。在线程被执行之前都是属于创建态(NEW),在调用start方法后,线程就会转成RUNABLE状态,在RUNABLE中,当线程处于就绪态(Ready)的时候,经过调度分配了cpu资源,这时转成了运行态,当线程被挂起、线程执行了yield,线程将会退回就绪态。在运行态(RUNABLE),也会通过一些处理而被阻塞或者等待。终止状态(TERMINATED)是线程执行完毕退出,此时,终止态的线程不会直接转成创建态。
在这里插入图片描述

Java线程状态代码

Java中线程的状态都是在java.lang.Thread.State的枚举类中。
可以看一下以下枚举代码,分别为(NEWRUNNABLEBLOCKEDWAITINGTIMED_WAITINGTERMINATED)六种。

public enum State {
    NEW,

    RUNNABLE,

    BLOCKED,

    WAITING,

    TIMED_WAITING,

    TERMINATED;
}

接下来看一下演示代码

public class T6_Thread_State {
    static class Thread1 extends Thread {
        @Override
        public void run() {
            System.out.println("run - 当前线程的状态: " + this.getState());
            for (int i = 0; i < 5; i++) {
                try {
                    System.out.println("sleep前 - 当前线程的状态: " + this.getState());
                    Thread.sleep(1000);
                    System.out.println("sleep后 - 当前线程的状态: " + this.getState());
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        Thread1 t1 = new Thread1();
        System.out.println("main - 当前线程的状态: " + t1.getState());
        t1.start();
        System.out.println("join前 - 当前线程的状态: " + t1.getState());
        t1.join();
        System.out.println("join后 - 当前线程的状态: " + t1.getState());
    }
}

运行结果,可以只管看到线程在运行过程种的状态切换。
在这里插入图片描述

博文推荐

这里推荐给各位一篇很不错的博客文章,是针对Java线程的状态转换的详细介绍

  • Java线程的6种状态及切换(透彻讲解)_潘建南的博客-CSDN博客_线程的5种状态

  • 线程池 waiting on condition_Java线程生命周期与状态切换_有所不知的博客-CSDN博客

👍创作不易,如有错误请指正,感谢观看!记得点赞哦!👍

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

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

相关文章

漏洞深度分析|CVE-2023-25141 sling-org-apache-sling-jcr-base存在JNDI注入漏洞

项目介绍 Apache Sling提供对可插入资源提供程序的支持。虽然这允许将自定义数据提供程序非常灵活和高效地集成到Sling中&#xff0c;但这种集成是在Sling的资源 API 级别上完成的。可能依赖于能够将资源适配到JCR节点并继续使用JCR API的遗留代码将不适用于此类资源提供者。 …

微信小程序自动化测试最佳实践(附 Python 源码)

目录&#xff1a;导读 小程序运行环境 微信小程序技术架构 使用 Chrome 调试小程序 小程序的性能测试 微信小程序的自动化测试​编辑 源码-微信小程序自动化测试 Python 版代码示例 小程序自动化测试需要跨过的几个坎 写在最后 随着微信小程序的功能和生态日益完善&…

“一号文件”聚焦三农,VR全景助农发展数字化

一号文件为何如此聚焦三农&#xff1f;因为三农是拼经济的基础&#xff0c;也是筑牢底盘的基本保证。现如今&#xff0c;农业基础还不稳固&#xff0c;而且城乡区域发展和居民收入差距依旧较大&#xff0c;为了解决城乡发展不平衡、农村发展不充分等矛盾&#xff0c;发展数字化…

Fuzz概述

文章目录AFL一些概念插桩与覆盖率边和块覆盖率afl自实现劫持汇编器clang内置覆盖率反馈与引导变异遗传算法fork server机制AFL调试准备AFL一些概念 插桩与覆盖率 边和块 首先&#xff0c;要明白边和块的定义 正方形的就是块&#xff0c;箭头表示边&#xff0c;边表示程序执行…

java有关类的初始化的分析

什么是类&#xff1f; 类是具有相同状态和相同行为的一组对象的集合 什么是对象&#xff1f; 万事万物皆为对象&#xff0c;可以理解为具体的个体就是对象 什么是面向对象的编程&#xff1f; 就是只在乎结果而不在乎过程&#xff0c;怎么理解这句话&#xff1f;举个例子&#x…

彻底废了,去干了两年外包...

先说一下自己的情况。大专生&#xff0c;17年通过校招进入湖南某软件公司&#xff0c;干了接近2年的点点点&#xff0c;今年年上旬&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落&#xff01;而我已经在一个企业干了五年的功能测试…

MacOS Ventura 13.2.1 (22D68) 正式版带 OC 0.8.9 and winPE 双分区原版黑苹果镜像

2 月 14 日消息&#xff0c;苹果今日向 Mac 电脑用户推送了 macOS 13.2.1 更新&#xff08;内部版本号&#xff1a;22D68&#xff09;&#xff0c;本次距离上次发布隔了 21 天&#xff0c;以修复Bug和安全更新为主。 镜像下载&#xff1a; 微信公众号&#xff1a; MacOS Vent…

docker 查看和分析镜像内文件

docker inspect docker inspect node:alpine查看元数据信息&#xff0c;一共有三层 "RootFS": {"Type": "layers","Layers": ["sha256:8c6806a0692459f603d074b4a7bdd38915650f1563f4ec728dad229475a52090","sha256:…

Python学习-----函数4.0(递归函数习题)

目录 递归算法 1.进制数转换 2.阶乘递归 3.递归获取两个数之间最小公倍数 4.递归获取两个数字之间最大公约数 5.斐波那契数列 5.递归求得数列的最值 6.倒序输出 7.递归二分法查找 递归算法 递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过…

部署JDK+tomcat上线jspgou项目

系列文章目录 文章目录系列文章目录一、前言二、Tomcat部署1、Tomcat Http Server2、安装MySQL3、部署jspgou&#xff08;电子商城&#xff09;一、前言 什么是JAVA虚拟机 所谓虚拟机&#xff0c;就是一台虚拟的计算机。他是一款软件&#xff0c;用来执行一系列虚拟计算机指令…

背景透明(opacity vs background)

最近在做项目的时候&#xff0c;遇到透明度的相关设置。 常用的背景透明设置可分为两种&#xff0c;分别是&#xff1a; 一是给background设置透明度。二是利用opacity属性。 在跳了一些坑之后&#xff0c;本人更推荐给background设置透明度&#xff0c;为什么呢&#xff1f;…

【QCA6174】SDX12 WiFi QCA6174 bdwlan30.bin和bdwlan30.txt相互转化操作说明

1.从高通获bin文件和txt文件相互转化工具 软件包名称 QCA6174_BDF_Converter.zip 2.解压工具包&#xff0c;解压之后包括以下文件 3.从sdx12 sdk拷贝bdwlan30.bin 路径如下&#xff0c;将bdwlan30.bin放到QCA6174_BDF_Converter目录下 ./cnss_proc_firmware/cnss_proc/wlan…

Twitter账号老被封?一文教会你怎么养号

昨天龙哥给大家科普完要怎么批量注册Twitter账号&#xff0c;立刻有朋友来私信龙哥说里面提到的这个养号和防关联具体是个怎么样的做法。由于Twitter检测机制还是比较敏感的&#xff0c;账号很容易被冻结&#xff0c;所以养号是非常重要的步骤。其实要养好Twitter账号其实并不难…

docker-compose极速部署kafka3.2.0集群(含zookeeper集群)

极速部署kafka3.2.0集群准备工作&#xff1a;准备三台服务器部署Zookeeper集群部署kafka集群创建Topic开启JMX_PORTkafka集群管理工具使用的 KakfaStreaming准备工作&#xff1a;准备三台服务器 服务器地址缩写192.168.0.200200192.168.0.201201192.168.0.202202 一、完成服务…

格创东智与金羽新能合作|先进工业互联网助力固态电池智能化运营

2022年12月&#xff0c;浙江金羽新能源科技有限公司&#xff08;以下简称金羽新能&#xff09;与格创东智签订战略合作框架协议&#xff0c;并在湖州安吉举行金羽新能固态电池MES项目启动会。 固态电池是一种使用固体电极和固体电解质的电池。相较传统锂电池&#xff08;液态电…

Android开发初识

文章目录一 Android发展历程二 开发工具Android Studio的发展历程三 硬件要求四 Android Studio 的安装和使用一 Android发展历程 安卓&#xff08;Android&#xff09;是一种基于Linux内核&#xff08;不包含GNU组件&#xff09;的自由及开放源代码的操作系统。 由美国Google公…

解药 or 毒药:ChatGPT辅助设计,规划师和建筑师要失业了吗?

​人工智能聊天机器人ChatGPT火爆全球&#xff0c; 规划师笔记也紧赶潮流&#xff0c;快速尝试&#xff0c; AI与设计发生碰撞&#xff0c; 会产生怎样的火花&#xff1f; 运用AI帮助写文案、作图、视频剪辑、游戏制作等等随着2021被称为元宇宙元年&#xff0c;近些年来AI在…

中国地图航线图(echarjs)

1、以上为效果图 需要jq、echarjs、china.json三个文件支持。以上 2、具体代码 DOM部分 <!-- 服务范围 GO--> <div class"m-maps"><div id"main" style"width:1400px;height: 800px; margin: 0 auto;"> </div> <!-…

【Java基础】021 -- 常见算法及API(查找、排序、Arrays)

目录 常见算法 1、企业中的常见算法 一、查找算法 1、基本查找&#xff08;数据没有任何顺序&#xff09; ①、代码实现&#xff1a; ②、课堂练习&#xff1a; 2、二分查找/折半查找&#xff08;数据一定要有顺序&#xff09; ①、示例情况&#xff1a; ②、代码实现&#xff…

一文搞懂ECU休眠唤醒之利器-TJA1145

前言 首先&#xff0c;小T请教大家几个小小问题&#xff0c;你清楚&#xff1a; 什么是TJA1145吗&#xff1f;你知道休眠唤醒控制基本逻辑是怎么样的吗&#xff1f;TJA1145又是如何控制ECU进行休眠唤醒的呢&#xff1f;使用TJA1145时有哪些注意事项呢&#xff1f; 今天&…