线程安全和对应的核心概念

线程安全

  • 线程安全的概念:当多个线程访问某一个类(对象和方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或者方法)就是线程安全的
  • synchronized:可以在任意对象及方法上加锁,而加锁的这段代码称为‘互斥区’或者“临界区”
  • 当多个线程访问myThread的run方法时,以排队的方式进行处理(这里排队是按照CPU分配的先后顺序而定的),一个线程想要实现synchronized装饰的方法里的代码,首先是尝试获取锁,如果可以得到锁,就可以执行synchronized代码体的内容;如果拿不到锁,这个线程就会不断尝试去获取锁资源,直到拿到为止;而且是多个线程同时去竞争这把锁(锁竞争)

Synchronized

  • 同步Synchronized:同步的概念就是共享,如果不是共享的资源就没有必要进行同步
  • 异步asynchronized:异步的概念就是独立,相互之间不受到任何制约
  • 同步的目的是为了保证线程的安全,对于线程安全需要保证两个特性 原子性(同步)和可见性

线程之间通信

  • 线程通信的概念:线程是操作系统中独立的个体,但是这些个体如果不经过特殊的处理就不能成为一个整体,线程之间的通信就成为整体的必用的方式之一。当线程之间存在通信指挥,系统之间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对于线程任务在处理过程中,进行有效的把控和监督
  • 使用wait/notify方法实现线程之间的通信(这两个方法都是object的类的方法,即java为所有的对象都提供了这两个方法)
  • wait和notify必须配合synchronized关键字使用
  • wait方法释放锁/notify方法不释放锁

ThreadLocal概念

  • 线程局部变量,是一种多线程间并发访问变量的解决方案,与synchronized等加锁的方式不同,ThreadLocal完全不提供锁,而使用以空间换时间的手段,为每个线程提供变量的独立副本,以保障线程的安全
  • 从性能上说,ThreadLocal不具有绝对的优势,在并发不是很高的情况下,加锁的性能可能会更好,但是作为一套与锁完全无关的线程安全解决方案,在高并发量或者竞争激烈的场景,使用ThreadLocal可以在一定程度上减少锁竞争

Volatile关键字核心概念与应用

  • Volatile:主要作用是使变量在多个线程之间可见
  • 阻止指令的重排序,happens-before
  • 一个线程可以执行的操作有使用(use)、赋值(assign)、转载(load)、存储(store)、锁定(lock)、解锁(unlock)
  • 主内存可以执行的操作有读(read)、写(write)、锁定(lock)、解锁(unlock),每个操作都是原子的
  • volatile的作用就是强制线程到主内存(共享内存)里去读取变量,而不是去线程工作内存里去读取,从而实现了多个线程之间变量的可见,也就是满足线程安全的可见行

JVM

  • Java Memory Model(Java内存模型),简称JVM,用于解决线程对于共享变量的写入何时对于另一个线程可见
  • 所有变量都存储在主内存中,每一个线程都有一个私有的本地内存,本地内存是将该线程使用到的变量,从主内存中拷贝到本地
  • 线程对于变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的变量(volatile变量也不例外)
  • happens-before规则,例如操作A :i=1;操作B:j=i;如果操作Ahappens-before操作B,那么操作B完成之后,j的值一定为1;
  • 因为happens-before关系可以向程序员保证,在操作B执行之前,操作A的执行后的影响【或者说明结果】(修改i的值)对于操作B是可以观察到的【可见的】

规则

  • 简而言之,使用happens-before概念来阐述操作之间的内存可见行
  • 程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作,也就是说,你写的操作,如果是单线程执行,那么前面的操作就会happens-before于后面的操作
  • 监视器锁规则:对于一个锁的解锁,happens-before于随后对这个锁的加锁
  • Volatile变量规则:对于一个volatile域的写,happens-before于任意后续对这个volatile域的读
  • 传递性规则:A happens-before B,B happens-before C,则A happens-before C

指令重排序

  • 为了保证程序的最终运行结果需要和在单线程严格意义的顺序化环境下执行的结果一致,程序指令的执行顺序有可能和代码的顺序不一致,这个过程就称之为指令的重排序
  • 指令的重排序的意义:JVM利用处理器的特性,充分利用多级缓存,多核等进行适当的指令重排序,从而可以充分利用CPU的执行特点,最大程度上发挥机器的性能

Atomic系列类比

  • Atomic系列类封装了一系列的基础类型和对象操作,其目的是为了实现原子性
  • AtomicInteger
  • AtomicLong
  • AtomicBoolean
  • AtomicIntegerArray
  • AtomicLongArray
  • AtomicReference
  • 注意:在对Atomic类操作的时候,如果有多个操作执行,那么就是非原子性的,需要加aynchronized进行修饰,保证Atomic类操作的整体原子性

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

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

相关文章

JDK Unsafe类的使用与CAS原子特性

JDK Unsafe类的使用与CAS原子特性 Java.util.concurrent.atomic包,其中包含了大量使用到Unsafe这个类Java不能直接访问操作系统的底层,而是通过本地方法来访问。 Unsafe类提供了硬件级别的原子操作,主要提供了以下功能 内存操作字段的定位和…

写软件不是造汽车

写软件和做其他事情是不一样的。当我们制造别的东西的时候——像汽车、玩具、椅子、画作、甚至包括数字产品如平面图片和3D模型——我们做出来的成品就是最终的结果。而开发软件则不是,我们做出来的产品永远不可能有最终的结果——我们需要向计算机解释如何根据任意…

网站盈利的10种方式

如果你有自己的网站,而且已经有了不少的流量,你肯定会开始考虑如何通过这个网站来挣一些钱。 在这篇文章中,我会向大家介绍网站最常见的10种盈利方式。 1.按点击付费广告 在网站上展示一个按点击付费的广告横幅是最简单的盈利方式&#xff…

Redis数据的类型

Redis一共分为五种基本数据类型:String、Hash、List、Set、Zset. string 内部编码有三种,raw,embstr,int String 是二进制的。可以存储序列化对象,图片,字符串,数值等 set和get方法 &#x…

Redis高级命令与特性以及单点模式的介绍

高级命令 keys * 返回满足条件的所有key,可以模糊匹配exists 是否存在指定的keypersist 取消过期时间select 选择数据库 (0-15,总共16个数据库)move key index 将当前数据库的 key 移动到给定的数据库 db 当中randomkey 随机返回…

同为程序员 为什么我的工资最低

我看着工资单上每一个开发团队成员的薪水,慢慢地我不能保持淡定了。 而当我看到我的工资排名是倒数的时候——靠近最后一名——我不由得倒抽一口冷气。就像圣诞故事中的那个可爱的小男孩Ralphie ,想买气枪却被忽悠会有危险一样,我也不断忽悠…

redis.conf配置文件详解

基本配置 daemonize no #是否以后台进程启动databases 16 #创建database的数量(默认选中的是database 0)save 900 1 #刷新快照到硬盘中,必须满足两者要求才会触发,即900秒之后至少1个关键字发生变化save 300 10 #必须是300秒之后至少10个关键字发生变…

用Unix的设计思想来应对多变的需求

摘要:无论是Unix设计,还是面向对象设计,还是别的什么如SOA,ECB,消息,事件,MVC,网络七层模型,数据库设计,等等,他们都在干三件事——解耦&#xff…

有关编程的12个猜想

摘要:编程世界的将来如何目前仍难预料,但可以肯定的一点是技术一直在加速发展。本文搜罗出12个独特的编程视角猜想,一起来看看有哪些猜想在不久的将来就能变为现实。 编程世界的将来如何目前仍难预料,但可以肯定的一点是技术一直…

面试中如何剔除“鱼目混珠”程序员?

公司招聘面试事宜是一个耗时耗钱的项目,从挑选简历开始,还要花更多的时间面试候选人。有的时候这些人才机构会向你保证这些人都是Java天才、SQL专家、堆栈开发者等等,但实际上真实情况远不及你想想的。对于一个公司来说,执行招聘面…

java容器相关问题

同步类容器 1,这些复合操作在多线程并发地修改容器时,可能会表现出意外的行为,最经典的便是ConcurrentModificationException,原因是当容器迭代的过程中,被并发的修改了内容,这是由于早期迭代器设计的时候…

趣文:如果编程语言是车

C语言是全能手,小巧,强大,所向披靡,可靠,任何事情都能对付。 C是新的C,双倍的能力,双倍的尺寸,适应险恶的环境,但是你如果没练好就去驾驶,很可能会撞车。 C#是…

开发者应该了解的API技术清单!

摘要:有人说,有API的地方就有App,借助这些API开发者轻松构建出一款应用,极大地提高开发效率和开发质量。文中整理了一份API服务清单,内容涵盖:监控/调试、 CDN 、数据库、仪表盘、支付、通信等方面&#xf…

提高程序员职场价值的10大技巧

如果你已经是个很牛叉的程序员,但是依然觉得觉得还不够的话,欢迎阅读此文。本文旨在帮助各位更上一层楼。 你是不是觉得自己已经掌握了所有的编程技巧?别太自以为是了! 会写代码的确很重要,但是要拿到更好薪水&#…

google python的风格规范

点击链接,查看内容

IT人应当知道的10个行业小内幕

如果你打算从事IT行业或刚进入这个行业,也许本文下面的小内幕会吓到你,因为这些事平常都不会公开讨论的。如果你是IT资深人士,或许你已经遇到其中的大部分了。如果你愿意,请一起来参与讨论吧。 这些内幕大多数是针对网络管理员、…

Volatile原子性一致性JVM指令重排

概念 Volatile概念:Volatile关键字的主要作用是使变量在多个线程间可见。作用: 在多线程间可以进行变量的变更,使得线程间进行数据的共享可见 阻止指令重排序,happens-before package com.example.core.cas;import com.example.c…

Java JUC工具类--CyclicBarrier

CyclicBarrier:栅栏的概念,多线程的进行阻塞,等待某一个临界值条件满足后,同时执行 类比:每个线程代表一个跑步运动员,当运动员都准备好后,才一起出发,只要有一个人没有准备好&#…

Java JUC工具类--Future

Future模式,也是非常经典的设计模式,这种模式主要就利用空间换时间的概念,也就是说异步执行(需要开启一个新的线程)在互联网高并发的应用服务中,我们随处可见这种理念和代码,主要就是使用了这种…