码出高效:Java开发手册笔记(线程安全)

news2024/11/25 7:15:08

    并发与并行的目标都是尽可能快地执行完所有任务。以医生坐诊为例,某个科室有两个专家同时出诊,这就是两个并行任务,其中一个医生,时而问诊,时而查看化验单,然后继续问诊,突然又中断去处理病人的咨询,这就是并发。在并发环境下,由于程序的封闭性全被打破,出现了以下特点:
    ( 1 )并发程序之间有相互制约的关系。 直接制约体现为一个程序需要另一个程序的计算结果;间接制约体现为多个程序竞争共享资源,如处理器、缓冲区等。
    ( 2 )并发程序的执行过程是断断续续的。 程序需要记忆现场指令及执行点。
    ( 3 )当并发数设置合理并且 CPU 拥有足够的处理能力时,并发会提高程序的运行效率。

线程安全

    线程可以拥有自己的操作栈、程序计数器、局部变量表等资源,它与同一进程内的其他线程共享该进程的所有资源。线程在生命周期内存在多种状态。如图 7-2 所示 ,有 NEW (新建状态)、 RUNNABLE (就绪状态)、 RUNNING (运行状态)、BLOCKED (阻塞状态)、 DEAD (终止状态)五种状态。
在这里插入图片描述
    ( 1 ) NEW ,即新建状态,是线程被创建且未启动的状态。 创建线程的方式有三种:第一种是继承自 Thread 类,第二种是实现 Runnable 接口,第三种是实现 Callable 接口。相比第一种,推荐第二种方式,因为继承自 Thread 类往往不符合里氏代换原则,
而实现 Runnable 接口可以使编程更加灵活,对外暴露的细节比较少,让使用者专注于实现线程的 run()方法上。第三种Callable 接口的 call() 声明如下:

@FunctionalInterface
public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

    由此可知,Callable 与 Runnable 有两点不同:第一,可以通过 call()获得返回值。前两种方式都有一个共同的缺陷,即在任务执行完成后 ,无法直接获取执行结果 , 需要借助共享变量等获取 ,而 Callable 和 Future 则很好地解决了这个问题;第二,call()可以抛出异常。而 Runnable 只有通过 setDefaultUncaughtExceptionHandler()的方式才能在主线程中捕捉到子线程异常。
示例:
Car类实现Runnable接口

package com.example.demo.test;

/**
 * @Author: Ron
 * @Create: 2023-04-21 14:38
 */
public class Car implements Runnable {

    @Override
    public void run() {
        int i = 1/0;
        System.out.println("Car");
    }
}

Airplane实现Callable接口

package com.example.demo.test;

import java.util.concurrent.Callable;

/**
 * @Author: Ron
 * @Create: 2023-04-28 14:18
 */
public class Airplane implements Callable {
    @Override
    public Object call() throws Exception {

        int i = 1/0;
        System.out.println("Airplane");
        return i;
    }
}

    ( 2 ) RUNNABLE ,即就绪状态 ,是调用start()之后运行之前的状态。线程的start()不能被多次调用,否则会抛出IllegalStateException 异常。
    ( 3 ) RUNNING ,即运行状态 , 是 run()正在执行时线程的状态。线程可能会由于某些因素而退出 RUNNING ,如时间、异常、锁、调度等。
    ( 4 ) BLOCKED ,即阻塞状态 , 进入此状态 , 有以下种情况。

  • 同步阻塞:锁被其他线程占用。
  • 主动阻塞:调用 Thread 的某些方法,主动让出 CPU 执行权 ,比如 sleep()、join()等。
  • 等待阻塞:执行了 wait()。

    ( 5 ) DEAD ,即终止状态,是 run() 执行结束,或同异常退出后的状态 , 此状态不可逆转。
    再用医生坐诊的例子说明 , 医生并发地处理多个病人的询问、开化验单、查看化验结果、开药等工作,任何一个环节一旦出现数据混淆,都可能引发严重的医疗事故。延伸到计算机的线程处理过程中,因为各个线程轮流占用 CPU 的计算资源,可能会出现某个线程尚未执行完就不得不中断的情况,容易导致线程不安全。例如,在服务端某个高并发业务共享某用户数据,首先 A 线程执行用户数据的查询任务 , 但数据尚未返回就退出 CPU 时间片;然后 B 线程抢占了 CPU 资源执行并覆盖了该用户数据 ,最后 A 线程返回到执行现场,直接将 B 线程处理过后的用户数据返回给前端,导致页面显示数据错误。为保证线程安全,在多个线程并发地竞争共享资源时,通常采用同步机制协调各个线程的执行,以确保得到正确的结果。

    线程安全问题只在多线程环境下才出现,单线程串行执行不存在此问题。保证高并发场景下的线程安全,可以从以下四个维度考量:
    ( 1 )数据单线程内可见。单线程总是安全的。通过限制数据仅在单线程内可见,可以避免数据被其他线程篡改。最典型的就是线程局部变量,它存储在独立虚拟机栈帧的局部变量表中,与其他线程毫无瓜葛。 ThreadLocal 就是采用这种方式来实现线程安全的。
    ( 2 )只读对象。只读对象总是安全的。它的特性是允许复制、拒绝写人。最典型的只读对象有 String 、 Integer 等。一个对象想要拒绝任何写人,必须要满足以下条件:使用 final 关键字修饰类,避免被继承;使用 private final 关键字避免属性被中途修改;没有任何更新方法;返回值不能可变对象为引用。
    ( 3 )线程安全类。某些线程安全类的内部有非常明确的线程安全机制。比如StringBuffer 就是一个线程安全类,它采用synchronized 关键字来修饰相关方法。
    ( 4 )同步与锁机制。如果想要对某个对象进行并发更新操作,但又不属于上述三类,需要开发工程师在代码中实现安全的同步机制。虽然这个机制支持的并发场景很有价值,但非常复杂且容易出现问题。
    线程安全的核心理念就是“要么只读,要么加锁”。合理利用好 JDK 提供的并发包,往往能化腐朽为神奇。 Java 并发包( java.util.concurrent ,JUC ) 中大多数类注释都写有@author Doug Lea。如果说 Java 是一本史书,那么 Doug Lea 绝对是开疆拓土的伟大人物。 Doug Lea 在当大学老师时,专攻并发编程和并发数据结构设计,主导设计了JUC 并发包,提高了 Java 并发编程的易用性,大大推进了 Java 的商用进程。并发包主要分成以下几个类族:
    ( 1 )线程同步类。这些类使线程间的协调更加容易,支持了更加丰富的线程协调场景,逐步淘汰了使用 Object 的 wait()和 notify()进行同步的方式。主要代表为CountDownLatch 、 Semaphore 、 CyclicBarrier 等。
    ( 2 )并发集合类。集合并发操作的要求是执行速度快,提取数据准。最著名的类非 ConcurrentHashMap 莫属,它不断地优化,由刚开始的锁分段到后来的 CAS,不断地提升并发性能。其他还有 ConcurrentSkipListMap、 CopyOnWriteArrayList、
BlockingQueue 等。
    ( 3 )线程管理类。虽然 Thread 和 ThreadLocal 在 JDK1.0 就已经引入,但是真正把 Thread 发扬光大的是线程池。根据实际场景的需要,提供了多种创建线程池的快捷方式,如使用 Executors 静态工厂或者使用 ThreadPoolExecutor 等。另外,通过
ScheduledExecutorService 来执行定时任务。
    ( 4 )锁相关类。锁以 Lock 接口为核心,派生出在一些实际场景中进行互斥操作的锁相关类。最有名的是 ReentrantLock。锁的很多概念在弱化,是因为锁的实现在各种场景中已经通过类库封装进去了。
    并发包中的类族有很多,差异比较微妙,开发工程师需要有很好的 Java 基础、逻辑思维能力,还需要有定的数据结构基础,才能够彻底分清各个类族的优点、缺点及差异点。
    解决线程安全问题的能力是开发工程师进阶的重要能力之一。由于初创公司的业务流量通常比较小,再加上其初级程序员缺乏线程安全意识。所以,即使出现了由高并发导致的错误,往往也由于复现难度大、追踪困难而不了了之。但是在后期的系统重构中,这些公司一定会为以上线程安全隐患买单。

package com.example.demo.test1;

/**
 * @Author: Ron
 * @Create: 2023-04-27 14:06
 */
public class ThreadNum {
    public static void main(String[] args) {
        new ThreadNum().testSynchronized();
    }

    public void testSynchronized(){
        synchronized (this){
            System.out.println("testSynchronized");
        }
    }
}

在这里插入图片描述

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

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

相关文章

总线、I/O总线、I/O接口

总线是计算机内数据传输的公共路径&#xff0c;用于实现两个或以上部件之间的信息交换。计算机系统中有多种总线&#xff0c;它们在各个层次上提供部件之间的连接和信息交换通路。 核内总线&#xff1a;在处理器核内部各元件之间连线的总线称为核内总线&#xff0c;可连接核内…

Java-数据结构-并查集<二>

一.并查集的简单介绍 二. 并查集的主要构成和实现方式 三.HashMap模板和数组模板 由于在下文的模板基本一致&#xff0c;不再每次都罗列&#xff0c;大体的模板如下&#xff0c;若有错误可以在leetcode找到对应的题目解答&#xff0c;已经附上连接。 HashMap class UnionFi…

本周大新闻|苹果首款MR没有主打卖点;Meta认为AI是AR OS的基础

​本周XR大新闻&#xff0c;AR方面&#xff0c;苹果首款MR或没有主打卖点&#xff0c;反而尽可能支持更多App和服务&#xff1b;扎克伯格表示基于AI的AR眼镜操作系统是下一代计算平台的基础&#xff1b;微软芯片工程VP Jean Boufarhat加入Meta芯片团队&#xff1b;Humane展示了…

[计算机图形学]高级光线传播与复杂外观建模(前瞻预习/复习回顾)

本篇不涉及技术细节* 一、高级光线传播* 1.有偏和无偏估计 无偏估计&#xff0c;比如我们在之前做路径追踪的时候&#xff0c;我们用许多样本去近似定积分的值&#xff0c;无论我们取的样本数量是多少&#xff0c;它的期望永远是对的&#xff0c;也就是我们真实的定积分的值&…

Python入门(一)Python概述与环境搭建

Python概述与环境搭建 1.概述1.1版本及下载1.2 Python 特点 2.环境搭建3.第一个程序“hello&#xff0c;world”4.可能会存在的问题 1.概述 Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&#xff0c;相比其他语言…

【WAF】雷池waf升级体验

文章目录 前言一、更新二、功能体验1.仪表板2.自定义规则&#xff1a;3. 通用配置&#xff1a; 更新总结新增优化&#xff1a; 前言 最近雷池有比较大的更新&#xff0c;安装可以参考以前文章雷池waf安装&#xff0c;更新了数据统计也就是仪表板和自定义规则和通用配置还有IP高…

AI行为分析预警系统 opencv

AI行为分析预警系统通过pythonopencv网络模型Ai视觉智能分析技术&#xff0c;AI行为分析预警系统可以对实际场景下如车间、电力场景、化工场景、工业生产场景下的人员作业操作行为规范进行有针对性的定制开发&#xff0c;根据每个项目的不同的识别预警需求。OpenCV可以在不同的…

BEV(0)---Transformer

1 Transformer Transformer是一个Sequence to Sequence model&#xff0c;特别之处在于它大量用到了self-attention&#xff0c;替代了RNN&#xff0c;既考虑了Sequence的全局信息也解决了并行计算的问题。 1.1 self-attention&#xff1a; ①. 输入x1 ~ x4为一个sequence&…

Mysql-SQL优化

SQL优化 插入数据优化1&#xff09;批量插入数据2&#xff09;手动控制事务3&#xff09;主键顺序插入大批量插入数据 主键优化order by优化group by优化limit优化count优化update优化小结 插入数据优化 插入数据优化主要是对于insert进行批量插入时优化&#xff0c;下面我们就…

验证二叉搜索树-递归双指针法

1题目 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a…

初识springboot【手把手教你搭建springboot项目】+springboot日志详解【超详细】

目录 一.springboot的概念 1.什么是springboot&#xff1f; 二.使用springboot进行开发的优势 springboot的设计原则是什么&#xff0c;使用springboot进行开发具有怎样的优势&#xff1f;&#xff08;M&#xff09; 三.手把手搭建一个springboot项目 ①创建项目并选择依赖…

枚举二进制数的子集

思想&#xff1a; 如1011的二进制子集有1011&#xff0c;1010&#xff0c;1001&#xff0c;1000&#xff0c;0011&#xff0c;0010&#xff0c;0001&#xff0c;0000 思想是每次对当前最小子元素-1与目标x取与运算。枚举到0为止。 成立原因&#xff1a;因为我们是由大到小&a…

Python使用AI photo2cartoon制作属于你的漫画头像

Python使用AI photo2cartoon制作属于你的漫画头像 1. 效果图2. 原理3. 源码参考 git clone https://github.com/minivision-ai/photo2cartoon.git cd ./photo2cartoon python test.py --photo_path images/photo_test.jpg --save_path images/cartoon_result.png1. 效果图 官方…

计算机组成原理 存储器(下)

Cache和主存之间的映射: Cache的基本结构 Cache存储体以块为单位和主存交换信息&#xff0c;地址变换机制是由CPU送往主存的数据转换为Cacche的地址&#xff0c;主存和Cache的大小相同所以 &#xff0c;如果能够建立对应关系&#xff0c;则代表命中。 Cache的读写操作 写操作…

链表:常见面试题-根据大小划分区域

将单向链表按某值划分为左边小、中间相等、右边大的形式 1&#xff09;将链表放入数组里&#xff0c;在数组上做partition&#xff08;类似快排&#xff09;&#xff0c;这是笔试时推荐的写法 2&#xff09;分为小、中、大三部分&#xff0c;再把各个部分之间串起来&#xff…

1. 异常概述

目录 1.1 什么是生活的异常 1.2 什么是程序的异常 1.3 异常的抛出机制 1.4 如何对待异常 1.1 什么是生活的异常 男主角小明每天开车上班&#xff0c;正常车程 1 小时。但是&#xff0c;不出意外的话&#xff0c;可能会出现意外。 出现意外&#xff0c;即为异常情况。我们会…

自动化测试和selenium的使用

目录 自动化测试定义 为什么选择selenium来作为我们web自动化测试的工具&#xff1f; 自动化测试定位元素 使用cssSelector定位 使用XPath 定位 操作测试对象 模拟手动从键盘输入 点击对象 获取页面文本 清除对象输入的文本内容 添加等待&#xff08;三种方式&#…

00 SQL介绍

什么是SQL Structured Query Language&#xff1a;结构化查询语言 其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式可能会存在一些不一样的地方&#xff0c;我们称为“方言”。 SQL通用语法 SQL 语句可以单行或多行书写&#xff0c;以分号结尾。 可使用空…

干货 | 如何让Zotero更加强大?这六个插件是您的不二之选!

Hello,大家好&#xff01; 这里是壹脑云科研圈&#xff0c;我是喵君姐姐~ Zotero是由安德鲁w梅隆基金会斯隆基金会以及美国博物馆和图书馆服务协会资助开发&#xff0c;是一个免费易用的文献管理软件&#xff0c;可协助我们收集、管理及引用研究资源&#xff0c;包括期刊、书籍…

系统集成项目管理工程师 笔记(第20章:知识产权管理、第21章:法律法规和标准规范)

文章目录 20.1.2 知识产权的特性 58420.2.1 著作权及邻接权 58520.2.2 专利权 58920.2.3 商标权 59221.3 诉讼时效 59921.6.3 标准分级与标准类型 60321.7.2 信息系统集成项目管理常用的技术标准 6061、基础标准2、开发标准3、文档标准4、管理标准 第20章 知识产权管理 584 20.…