Thread的小补丁

Thread小补丁

  • 线程状态
    • New
    • Runnable
    • Waiting
    • Timed_waiting
    • Blocked
  • 线程安全
    • 线程的抢占式执行
    • 同时对同一个变量进行修改
    • 指令重排序
    • 操作不是原子的
  • 解决方案
    • 万恶之源
    • 优化我们自己的代码
    • Synchronized和Volatile

上一篇博客中,我们简单介绍了线程Thread的一些知识,一些基本的使用,但是单单只是知道那么一点是远远不够的,这篇博客中我们将简单介绍线程的状态,以及线程中的重头戏:线程安全

线程状态

New

当我们创建好Thread类但是并没有start(),也就是说并没有真正创建好线程的时候,就会是这个状态,这也就是我们说的各就各位,预备的意思:

        Thread thread = new Thread(()->{
        });
        System.out.println(thread.getState());

在这里插入图片描述

Runnable

Runnable就表示线程已经跑起来了或者说随时随地都可以上CPU,上战场的感觉:

        Thread thread = new Thread(()->{
            while (true){
                System.out.println("hi,t");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        System.out.println(thread.getState());

在这里插入图片描述

Waiting

Object object = new Object();
            Thread t1 = new Thread(()->{
                synchronized (object){
                    while (true){
                        System.out.println("hi,t1");
                        try {
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            });

            t1.start();
            Thread t2 = new Thread(()->{
                synchronized (Demo7.class){

                }
            });

            t2.start();
            System.out.println(t1.getState());

在这里插入图片描述

Timed_waiting

Object object = new Object();
            Thread t1 = new Thread(()->{
                synchronized (object){
                    while (true){
                        System.out.println("hi,t1");
                        try {
                            Thread.sleep(100000);
//                            object.wait();
                            //wait
                            //1.释放锁
                            //2.阻塞
                            //3.等待唤醒拿到锁
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            });

            t1.start();
            Thread t2 = new Thread(()->{
                synchronized (Demo7.class){

                }
            });

            t2.start();
            System.out.println(t1.getState());

在这里插入图片描述

Blocked

        Object object = new Object();
            Thread t1 = new Thread(()->{
                synchronized (object){
                    while (true){
                        System.out.println("hi,t1");
                        try {

                            Thread.sleep(100000);
//                            object.wait();
                            //wait
                            //1.释放锁
                            //2.阻塞
                            //3.等待唤醒拿到锁
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            });

            t1.start();
            Thread t2 = new Thread(()->{
                synchronized (object){

                }
            });

            t2.start();
            System.out.println(t1.getState());
            System.out.println(t2.getState());

在这里插入图片描述

线程安全

线程安全问题是面壁笔试的常客,阿涛在这里尽量精简地给大家说说有关线程安全!
首先我们这里说的安全的意思是不尽如人意,并不是和危险相对应的那个安全的意思,有很多代码我们在单线程环境下能够正常使用,但是到了多线程就会漏洞百出,下面我们先来讲讲造成线程不安全的几个重要原因:

线程的抢占式执行

线程之间是抢占式执行的,大丈夫生于天地之间,岂能郁郁久居人下!大家出来混,都是线程,谁比谁高贵啊,凭什么你就比我先执行?线程第一篇博客的时候我就给大家讲过,一般情况下,main线程是会先执行的,但是极少数情况下,就会有那么一个跑的快的线程比mian线程快,俗称"水鬼"!
大家要记住线程的抢占式执行是诱发多线程不安全的"万恶之源"!

同时对同一个变量进行修改

注意我们这里的关键词:“同时”,“同一变量”,“修改”,换句话说当我们"不同时",“对不同变量”,“只读”,都是不会造成线程不安全的,其实也很好理解,两个线程都是修改的话,最终结果不论是判给谁,都不是我们所能够接受的!

指令重排序

指令重排序是编译器自动对我们的代码进行地智能优化,编译器会在不改变我们代码结果的情况下自动地对我们的代码进行一定的优化,一般在单线程情况下这里的优化做的是很好的,但是到了多线程,谁知道因为抢占式执行会出现什么幺蛾子呢?
就比如我们说的创建实例这个操作吧:创建实例,我们首先是会先申请一块内存空间,然后调用构造方法,最后会把创建好的实例对象放在内存里面去,但是在多线程情况下就有这样一种可能:我们还是先申请了一块空间,然后我们直接就把实例给了这个空间,最后我们才进行构造方法,请注意,我们这里的是多线程情况下,也就是说我们有一个线程本想拿到的是已经搭建好的实例对象,但是阴差阳错只是拿到了一个空空如也的对象,那么无论我们想要进行什么后续操作,那都是空中阁楼,都是纸上谈兵.

操作不是原子的

我个人感觉上面的对同一个变量进行修改是这个不是原子情况的一个具体的例子,这里我就不给兄弟们画图了,兄弟们自己脑补一下:就以自增操作为例,我们首先是要把内存中的值加载到寄存器上,然后对内存其上面的值进行自增,最后才是把内存器上面的值加载回内存中去,如果我们想要对同一个变量进行两次自增的话,有没有一种可能两次加载到寄存器的时间比较接近,于是与两个寄存器上面的值是同一个,那么我们这次自增操作就从最终的结果上看来也就是只自增了一次.
关键就是在于,自增操作分了三步走,如果我们现在有能力让这三部变成一步,那么是不是就可以有效解决这个问题呢?

解决方案

万恶之源

万恶之源是多线程编程自身与生俱来的问题,除非你有本事多线程底层逻辑优化优化,不然应该是只能选择接收适应它

优化我们自己的代码

针对同一个变量进行修改的问题,有的时候我们是可以通过优化自己写的代码,达到解决问题的效果的,就像之前我们在JDBC编程事务那块学习的,我们有时候可以让部分代码串行执行,诸如此类的方法并不罕见

Synchronized和Volatile

synchronized关键字可以解决我们说的很多的问题,加锁既可以让锁中的代码编程原子的,也可以解决内存可见性的问题:内存可见性就是当我们在一边读一边修改代码的时候,我们读取数据的速度是飞快的,如果我们一直在读取一个数据,并且每一次读取到的数据都是一样的,那么编译器就会大胆地帮我们进行一个优化,会把内存中的数据给加载到寄存器中,那么以后我们就不再会去内存中读数据了,就直接去寄存器中读数据了,从某种意义上来说这也是编译器的优化造成的,
而我们的Volatile关键字也是可以解决我们的内存可见性问题的,这就是手动关闭了我们的优化.
好了,今天关于线程的一些关键的知识到这里也就差不多了,希望我的博客能够帮助到大家!
百年大道,你我共勉!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构和算法(1):数组

目录概述动态数组二维数组局部性原理越界检查概述 定义 在计算机科学中,数组是由一组元素(值或变量)组成的数据结构,每个元素有至少一个索引或键来标识 In computer science, an array is a data structure consisting of a col…

文心一言发布,你怎么看?chatGPT

百度全新一代知识增强大语言模型“文心一言”于2021年3月16日正式发布,作为一款自然语言处理技术,它引起了广泛的关注和讨论。 首先,文心一言是一款具有重大意义的自然语言处理技术。在人工智能领域,自然语言处理技术一直是一个难…

PyTorch 之 神经网络 Mnist 分类任务

文章目录一、Mnist 分类任务简介二、Mnist 数据集的读取三、 Mnist 分类任务实现1. 标签和简单网络架构2. 具体代码实现四、使用 TensorDataset 和 DataLoader 简化本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052 一、Mnist 分类任…

Lambda表达式

第一章 Java为什么引入 Lmabda表达式目的尽可能轻量级的将代码封装为数据1.1 什么是Lambda表达式Lambda表达式也被成为箭头函数、匿名函数、闭包 Lambda表达式体现的是轻量级函数式编程思想 ‘->’符号是Lambda表达式的核心符号,符号左侧是操作参数,符…

YOLOv8 多目标跟踪

文章大纲 简介环境搭建代码样例跟踪原理代码分析原始老版实现新版本封装代码实现追踪与计数奇奇怪怪错误汇总lap 安装过程报错推理过程报错参考文献与学习路径简介 使用yolov8 做多目标跟踪 文档地址: https://docs.ultralytics.com/modes/track/https://github.com/ultralyt…

【多线程】多线程案例

✨个人主页:bit me👇 ✨当前专栏:Java EE初阶👇 ✨每日一语:we can not judge the value of a moment until it becomes a memory. 目 录🍝一. 单例模式🍤1. 饿汉模式实现🦪2. 懒汉模…

java如何创建线程

java如何创建线程1. java如何创建线程1.1 通过继承Thread类来创建线程1.2 通过实现Runnable接口来创建线程1.3 通过匿名内部类来创建线程1.4 lambda表达式1.5 通过实现Runnable接口的方式创建线程目标类的优缺点1. java如何创建线程 一个线程在Java中使用一个Thread实例来描述…

android8 rk3399 同时支持多个USB摄像头

文章目录一、前文二、CameraHal_Module.h三、CameraHal_Module.cpp四、编译&烧录Image五、App验证一、前文 Android系统默认支持2个摄像头,一个前置摄像头,一个后置摄像头需要支持数量更多的摄像头,得修改Android Hal层的代码 二、Camer…

VueX快速入门(适合后端,无脑入门!!!)

文章目录前言State和Mutations基础简化gettersMutationsActions(异步)Module总结前言 作为一个没啥前端基础(就是那种跳过js直接学vue的那种。。。)的后端选手。按照自己的思路总结了一下对VueX的理解。大佬勿喷qAq。 首先我们需要…

我的 System Verilog 学习记录(11)

引言 本文简单介绍 SystemVerilog 的其他程序结构。 前文链接: 我的 System Verilog 学习记录(1) 我的 System Verilog 学习记录(2) 我的 System Verilog 学习记录(3) 我的 System Verilo…

Linux lvm管理讲解及命令

♥️作者:小刘在C站 ♥️个人主页:小刘主页 ♥️每天分享云计算网络运维课堂笔记,努力不一定有收获,但一定会有收获加油!一起努力,共赴美好人生! ♥️夕阳下,是最美的绽放&#xff0…

软件行业的最后十年【ChatGPT】

在这篇文章中,我将说明像 ChatGPT 这样的生成式人工智能 (GAI) 将如何在十年内取代软件工程师。 预测被离散化为 5 个阶段,总体轨迹趋向于完全接管。 但首先,一个简短的前言。 推荐:用 NSDT场景设计器 快速搭建3D场景。 1、关于AI…

二叉搜索树:AVL平衡

文章目录一、 二叉搜索树1.1 概念1.2 操作1.3 代码实现二、二叉搜索树的应用K模型和KV模型三、二叉搜索树的性能分析四、AVL树4.1 AVL树的概念4.2 AVL树的实现原理4.3 旋转4.4 AVL树最终代码一、 二叉搜索树 1.1 概念 二叉搜索树( Binary Search Tree,…

LeetCode刷题记录---数位DP算法

😄 学会数位dp算法,可以连杀好几道力扣困难题,加油~ 🚀题目: 难度题目困难2376. 统计特殊整数困难1012. 至少有 1 位重复的数字困难233. 数字 1 的个数困难面试题 17.06. 2出现的次数🚀学习资料: 数位dp算法,我是跟着灵神学的,感谢灵神!数位 dp 通用模板参考灵神…

Python数据分析案例24——基于深度学习的锂电池寿命预测

本期开始案例较为硬核起来了,适合理工科的硕士,人文社科的同学可以看前面的案例。 案例背景 这篇文章是去年就发了,刊物也印刷了,现在分享一部分代码作为案例给需要的同学。 原文链接(知网文章 C核)&…

python如何快速采集美~女视频?无反爬

人生苦短 我用python~ 这次康康能给大家整点好看的不~ 环境使用: Python 3.8 Pycharm mou歌浏览器 mou歌驱动 —> 驱动版本要和浏览器版本最相近 <大版本一样, 小版本最相近> 模块使用: requests >>> pip install requests selenium >>> pip …

不是,到底有多少种图片懒加载方式?

一、也是我最开始了解到的 js方法&#xff0c;利用滚动事件&#xff0c;判断当时的图片位置是否在可视框内&#xff0c;然后进行渲染。 弊端&#xff1a;代码冗杂&#xff0c;你还要去监听页面的滚动事件&#xff0c;这本身就是一个不建议监听的事件&#xff0c;即便是我们做了…

【selenium学习】数据驱动测试

数据驱动在 unittest 中&#xff0c;使用读取数据文件来实现参数化可以吗&#xff1f;当然可以。这里以读取 CSV文件为例。创建一个 baidu_data.csv 文件&#xff0c;如图所示&#xff1a;文件第一列为测试用例名称&#xff0c;第二例为搜索的关键字。接下来创建 test_baidu_da…

百度生成式AI产品文心一言邀你体验AI创作新奇迹:百度CEO李彦宏详细透露三大产业将会带来机遇(文末附文心一言个人用户体验测试邀请码获取方法,亲测有效)

百度生成式AI产品文心一言邀你体验AI创作新奇迹中国版ChatGPT上线发布强大中文理解能力超强的数理推算能力智能文学创作、商业文案创作图片、视频智能生成中国生成式AI三大产业机会新型云计算公司行业模型精调公司应用服务提供商总结获取文心一言邀请码方法中国版ChatGPT上线发…

贪心算法的原理以及应用

文章目录0、概念0.1.定义0.2.特征0.3.步骤0.4.适用1、与动态规划的联系1.1.区别1.2.联系2、例子3、总结4、引用0、概念 0.1.定义 贪心算法&#xff08;greedy algorithm &#xff0c;又称贪婪算法&#xff09;是指&#xff0c;在对问题求解时&#xff0c;总是做出在当前看来是…
最新文章