高并发:
cpu -- 缓存 -- 内存
资源利用率
公平性
便利性
 
生活举例 --- 串行任务中的异步性:我在烧水的时候看书 --- 平衡点
 
安全性问题 --- 产生竞态条件
共享数据 --- 共享相同的内存地址,并且并行执行
不可破坏 --- 永远不要发生最糟糕的事情
活跃性问题 --- 某个正确的事情最终会发生
某个操作无法执行下去
 
性能问题 --- 频繁的上下文切换,CPU花更多的时间在线程调度上

编写安全的多线程代码,核心在于对状态访问操作进行管理
共享(Shared):可被多线程访问
可变(Mutable) :在对象生命周期内可发生变化
对象状态,存储在状态变量(实例或静态域)中的数据,对象状态还可能依赖其他对象域
 
在程序访问对象的角度看这个问题
一个对象是否线程安全,取决于它是否被多线程访问。使用同步机制保证线程安全
 
需使用同步机制的情况:
当多线程访问一个状态变量,并且其中有一个线程进行写入操作时,必须采用同步机制协同线程对变量的访问
Java的同步机制
synchronized --- 重量级,独占加锁。
volatile类型变量
显式锁
原子变量
 
当多线程访问状态变量时,没有采取适合的同步机制则:
不在线程之间共享该变量
将状态变量改为不可变的变量
在访问状态变量时使用同步
 
线程安全类
线程安全程序
线程安全的程序是否完全由线程安全类构成?
完全由线程安全类构成的程序不一定线程安全。线程安全类中也可以包含非线程安全的类

线程安全性
多线程下的正确性 --- 当多线程下访问某个类,这个类始终都能保证正确的行为
单线程下的正确性 --- 所见即所得
 
无状态对象一定是线程安全的
 
原子性问题,修改变量时,实际可能并不是原子操作(读取---修改---写入),多线程下可能由于时序问题产生的数据不一致-----竞态条件 --- 安全性问题
先检查后执行 --- 通过一个可能失效的结果决定下一步动作
e.g A去地点Q的星巴克与B会面,到达Q之后发现有两家星巴克分别叫S1,S2.在S1没有看到B,然后去到S2也没有看到B,B迟到,B在A离开S1后到了S1,B到达S2但是B去S1找A.
 
延迟加载的竞态条件

竞态条件和数据竞争(Data Race)
数据竞争:在访问共享变量的非final类型的域时没有采用同步进行协同,那么就会出现数据竞争。当一个线程写入一个变量,另一个线程读取这个变量,或者读取一个之前由另一个线程写入的变量时,
并且这两个线程直接没有使用同步,就会出现数据竞争。不是所有竞态条件都是数据竞争,同样并非所有数据竞争都是竞态条件,但两者都会导致并发程序失败。
 
如何保证原子性:
复合操作保证原子性
原子操作:对于访问同一个状态的所有操作(包括该操作本身)来说,这个操作是一个以原子方式执行的操作
 
待解决的小功能 --- 实现一个因式分解 (缓存上一次计算的结果)
 
保存状态一致(一致性),需要带单个原子操作中更新所有相关的状态变量
 
内置锁(监视器锁)--- 是一个互斥锁,即A尝试获取由B线程持有的锁时,A会阻塞,且等到B释放锁后A才能重新获得锁
synchronized(lock){
}
作为所的对象引用
这个锁保护的代码块
 
重入
内置锁是可重入的,当一个线程试图获取它已经持有的锁时,这个请求会成功。其他线程尝试获取会阻塞unt 。获取锁的粒度是线程,而不是调用。
countNum = 0 --没有线程持有锁
countNum = 1 -- 当前有一个线程持有锁
重入CountNum++
在释放时,会依次递减 --- 直到为0
 
 
用锁保护状态
对于可能被多个线程同时访问的可变状态变量,在访问它时,都需要持有同一把锁 ---- 这个变量由这个所保护
对于每个包含多个变量的不变性条件,其中所涉及到的变量都需要同一把锁来保护
synchronized可保证单个操作的原子性,但是保证不了符和操作的原子性
当执行较长时间计算,可能无法快速完成操作时,一定不要持有锁

 

Java并发编程杂记(1)的更多相关文章

  1. Java并发编程杂记(2)

    对象共享 synchronized 设定原子性确定临界区 + 内存可见性 要解决如下问题 防止一个线程在使用对象状态而另一个线程在修改对象状态:且当一个线程修改了对象状态后,对其他线程可见.   可见 ...

  2. 【Java并发编程实战】----- AQS(四):CLH同步队列

    在[Java并发编程实战]-–"J.U.C":CLH队列锁提过,AQS里面的CLH队列是CLH同步锁的一种变形.其主要从两方面进行了改造:节点的结构与节点等待机制.在结构上引入了头 ...

  3. 【Java并发编程实战】----- AQS(三):阻塞、唤醒:LockSupport

    在上篇博客([Java并发编程实战]----- AQS(二):获取锁.释放锁)中提到,当一个线程加入到CLH队列中时,如果不是头节点是需要判断该节点是否需要挂起:在释放锁后,需要唤醒该线程的继任节点 ...

  4. 【Java并发编程实战】----- AQS(二):获取锁、释放锁

    上篇博客稍微介绍了一下AQS,下面我们来关注下AQS的所获取和锁释放. AQS锁获取 AQS包含如下几个方法: acquire(int arg):以独占模式获取对象,忽略中断. acquireInte ...

  5. 【Java并发编程实战】-----“J.U.C”:CLH队列锁

    在前面介绍的几篇博客中总是提到CLH队列,在AQS中CLH队列是维护一组线程的严格按照FIFO的队列.他能够确保无饥饿,严格的先来先服务的公平性.下图是CLH队列节点的示意图: 在CLH队列的节点QN ...

  6. 【Java并发编程实战】-----“J.U.C”:CountDownlatch

    上篇博文([Java并发编程实战]-----"J.U.C":CyclicBarrier)LZ介绍了CyclicBarrier.CyclicBarrier所描述的是"允许一 ...

  7. 【Java并发编程实战】-----“J.U.C”:CyclicBarrier

    在上篇博客([Java并发编程实战]-----"J.U.C":Semaphore)中,LZ介绍了Semaphore,下面LZ介绍CyclicBarrier.在JDK API中是这么 ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  9. Java并发编程:volatile关键字解析

    Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在 ...

随机推荐

  1. SpringBoot 源码解析 (六)----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)

    Spring Boot默认使用Tomcat作为嵌入式的Servlet容器,只要引入了spring-boot-start-web依赖,则默认是用Tomcat作为Servlet容器: <depend ...

  2. ACM-ICPC 2018 I. Characters with Hash

    I. Characters with Hash Mur loves hash algorithm, and he sometimes encrypt another one's name, and c ...

  3. C#控制打印机通过不同纸盒/进纸口进纸打印

    通常我们是通过程序操作打印机打印我们设置好的内容,但基本都是打印机默认进纸口打印:最近有一个通过C#程序控制两个进纸口分别进一张纸进行打印的需求,通过偿失找到了解决方案如下: 关于C#调用打印机打印的 ...

  4. Spring的整体架构的认识

    Spring的整体架构的认识 一).spring是用来做什么的? spirng使用基本的JavaBean来完成以前EJB所完成的事. 二).EJB EJB: Enterprise JavaBean, ...

  5. pdf 在线预览之 pdfjs插件

    这个插件不需要阅读器 也不会屏蔽签章 但是也是兼容到ie11

  6. 2019-9-25:渗透测试,基础学习,medusa爆破学习

    Medusa(美杜莎)暴力破解使用 该文章仅供学习,利用方法来自网络文章,仅供参考 一.简介 medusa(美杜莎)是一个速度快,支持大规模并行,模块化,爆破登陆,可以同时对多个主机,用户或是密码执行 ...

  7. Netty学习篇⑥--ByteBuf源码分析

    什么是ByteBuf? ByteBuf在Netty中充当着非常重要的角色:它是在数据传输中负责装载字节数据的一个容器;其内部结构和数组类似,初始化默认长度为256,默认最大长度为Integer.MAX ...

  8. HTML、CSS基础知识

    前端基础 1. CSS 8 1.1. CSS叫做层叠样式表,用来设置页面中元素的样式.背景颜色.字体颜色.字体大小... 8 1.2. CSS负责结构.表现.行为中的表现 8 1.3. 编写的位置 8 ...

  9. Github上传大文件(超过100M)

    上传大文件(超过100M)到Github 笔者上传操作100M的文件到Github,结果在push的时候会自动终止.然后提示无法上传大文件,就算删除再提交也是报错. 于是,本人写这篇博客就是为了解决这 ...

  10. Python--将文件夹中图片按照横屏竖屏进行分类

    搬运链接:https://www.jianshu.com/p/c8be54282e77 """ 可以遍历输入的路径的指定后缀的文件,主要是用来筛选图片,将图片分成 横屏, ...