3.1串行、并发与并行

  1.串行:一件事做完接着做下一件事。

  2.并发:几件事情交替进行,统筹资源。

  3.并行:几件事情同时进行,齐头并进,各自运行直到结束。

多线程编程的实质就是将任务处理方式由串行改为并发,即实现并发化

3.2竞态

  状态变量:即类的实例变量、静态变量。可以被多个线程共享,也被称为共享变量。

  共享变量: “可以”(不代表一定)被多个线程共同访问的变量。

  多线程编程中对于同样的输入,程序输出的结果的正确性与时间有关的现象就被称为竞态,也就是说计算结果时而正确时而错误。

  竞态常常是因为读取脏数据问题,即读取到一个过时的数据、丢失更新问题。二维表分析法是分析竞态问题的一种简单而有效的方法。

3.3竞态的模式与竞态产生的条件

  3.3.1竞态的两种模式

  read-modify-write(读-改-写) 和 check-then-act(监测而后行动)

 if(sequence >= 999){ // 监测而后行动
sequence = 0;
} else {
sequence++; // 读-改-写
}

  3.3.2竞态产生的条件

   访问(读取、更新)同一组共享变量的多个线程所执行的操作相互交错。

  3.3.3 消除竞态

   1.将共享变量改为局部变量。

   2.在访问共享变量的方法上加锁,synchronize关键字,使得该方法涉及的共享变量在任意时刻只能有一个线程访问。

3.4线程安全性

   线程安全:如果一个类在单线程环境下能够运作正常,并且在多线程环境下,在其使用方不必为其做任何改变的情况下也能正常运行。不会导致竞态

   非线程安全: 如果一个类在单线程环境下运行正常而在多线程环境下无法正常运行。会导致竞态,例如ArrayList、HashMap和SimpleDateFormat

  3.4.1原子性

   1.指访问(读、写)某个共享变量的操作从其执行线程以外的任何线程来看,该操作要么已经执行结束,要么尚未发生,即其他线程不会“看到”该操作执行了部分的中间效果。

   2.实现原子性的方式有加锁synchronize关键字(软件锁),还有CAS指令(硬件锁)。

   3.long型和double型以外的任何类型的变量的写操作都是原子操作。包括byte、short、int、char、boolean、float、String。为了保障long/double写操作的原子性,需要加volatile关键字修饰。 4.原子操作+原子操作 != 原子操作。

   3.4.2可见性

    可见性就是指一个线程对共享变量的更新的结果,对于读取相应共享变量的线程而言是否可见(能否读取到更新后的结果)的问题。

    单处理器系统实现的多线程编程也可能出现可见性问题。

    父线程在子线程启动之前对共享变量的更新对子线程的可见性是有保障的。父线程在子线程启动之后对共享变量的更新对子线程的可见性是没有保障的。  

    可见性的保障是通过使更新共享变量的处理器执行冲刷处理器缓存的动作,并使读取共享变量的处理器执行刷新处理器缓存的动作。java中通过对共享变量加volatile关键字修饰来保障可见性。

   3.4.3有序性

    感知顺序和源代码顺序一致,即有序性。volatile关键字、synchronized关键字都能够实现有序性。

    可见性是有序性的基础。有序性影响可见性。

3.5上下文切换   

   一个线程被暂停,即被剥夺处理器的使用权,另外一个线程被选中开始或者继续运行的过程就叫做线程上下文切换。

  切出:一个线程被剥夺处理器的使用权而被暂停运行。

  切入:一个线程被操作系统选中占用处理器开始或者继续其运行。

  上下文:切出和切入的时候操作系统需要保存和恢复相应线程的进度信息,这个进度信息就被称为上下文。

  多线程编程想必单线程编程来说,意味着更多的上下文切换,因此,多线程编程不一定比单线程的计算效率更高。

    3.5.1上下文切换的分类和具体诱因

  自发性上下文切换:Thread.sleep(); Object.wait();Thread.yield();Thread.join();LockSupport.park();I/O操作或者等待其他线程持有的锁。

  非自发性上写文切换:时间片用完了;线程优先级更高的线程需要被运行;java虚拟机的垃圾回收动作。

3.6线程的活性故障

    线程活性故障:由于资源稀缺性或者程序自身的原因和缺陷导致线程一直处于非RUNNABLE状态,或者线程虽然处于RUNNABLE状态但是其要执行的任务却一直无法进展的现象叫做线程活性故障。

  死锁:例如:一个线程X持有资源A的时候等待另一个线程释放资源B。而另一个线程Y在持有资源B的时候却等待线程X释放资源A。死锁的外在表现就是当事线程的生命周期状态永远处于非RUNNABLE状态。

  锁死:例如:一个线程X始终在等待资源或者锁而一直处于非RUNNABLE状态。

  活锁:例如:一个线程在执行时,一直无法结束而一直处于RUNNABLE状态,并且线程所要执行的任务却丝毫没有进展。即线程可能一直在做无用功。

  饥饿:饥饿就是线程因无法获得其所需的资源而使得任务执行无法进展的现象。

3.7资源争用与调度

  资源的争用与调度:由于资源的稀缺性或者资源本身的特性,我们往往需要在多个线程间共享同一个资源。

  排他性资源:

  资源争用:在一个线程占用一个排他性资源进行访问(读、写操作)而未释放其对资源所有权的时候,其他线程试图访问该资源的现象就被称为资源争用。争用是在并发环境下产生的一种现象。

 资源调用的一种常见策略就是排队。资源调度器内部维护一个等待队列。通常,被存入等待队列的线程会被暂停,当相应的资源被其持有线程释放时,等待队列中的一个线程会被选中唤醒而再次获得申请自愿的机会。被唤醒的线程如果申请到资源的独占权,那么该线程会从等待队列中移除。

  公平的调度策略不允许插队的现象,而非公平的调度策略则允许允许插队的现象。即一个线程释放器资源独占权的时候,等待队列中的一个线程会被唤醒再次申请相应的资源。极端的情况下非公平调度策略可能导致等待队列中的线程永远无法获得其所需的资源,会出现饥饿

  

学习笔记《Java多线程编程实战指南》三的更多相关文章

  1. Java多线程编程实战指南(核心篇)读书笔记(三)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76686044冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  2. Java多线程编程实战指南(核心篇)读书笔记(五)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76730459冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  3. Java多线程编程实战指南(核心篇)读书笔记(四)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76690961冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  4. Java多线程编程实战指南(核心篇)读书笔记(二)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76651408冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  5. Java多线程编程实战指南(核心篇)读书笔记(一)

    (尊重劳动成果,转载请注明出处:http://blog.csdn.net/qq_25827845/article/details/76422930冷血之心的博客) 博主准备恶补一番Java高并发编程相 ...

  6. 《Java多线程编程实战指南(核心篇)》阅读笔记

    <Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...

  7. 学习笔记《Java多线程编程实战指南》二

    2.1线程属性 属性 属性类型及用途  只读属性  注意事项 编号(id) long型,标识不同线程  是  不适合用作唯一标识 名称(name) String型,区分不同线程  否  设置名称有助于 ...

  8. 学习笔记《Java多线程编程实战指南》一

    1.1什么是多线程编程 多线程编程就是以线程为基本抽象单位的一种编程范式,和面向对象编程是可以相容的,事实上Java平台中的一个线程就是一个对象.多线程编程不是线程越多越好,就像“和尚挑水”的故事一样 ...

  9. Java多线程编程实战指南 核心篇 读书笔记

    锁 volatile CAS final static 原子性保障 具备 具备 具备 不涉及 不涉及 可见性保障 具备 具备 不具备 不具备 具备① 有序性保证 具备 具备 不涉及 具备 具备② 上下 ...

随机推荐

  1. 2018-No.7-SicnuCtf

    5月份的比赛现在才有时间在博客贴出来,这是我第二次出题了,第一次是上届的初赛,这次是决赛的题. 签到(base_or_base) 解压得到两个文件小明.zip和......txt,根据文件名提示猜测是 ...

  2. C# socket通讯 send方法记录

    由于本人是Java入门的开发,在C#开发中遇到的问题,在此记录一下: 1.client端的send方法不管发送出去没发送出去,总是显示发送出去. 查资料得知,send方法是将数据发送到缓存区,并不是直 ...

  3. 小程序视频播放组件video

    最近在做一个视频播放的功能,要求如下: 1.实现视频的全屏播放: 2.实现视频相关信息的展示: 3.实现视频滑动上下切换效果: 肯定选择用原生组件video了,真是不用不知道,一用都是坑: 首先,组件 ...

  4. python库-Arrow处理时间

    Arrow是一个处理时间的python库,能一键转换dates/times/timestamps等时间格式而不需要大量导致各种时间模块和格式转换函数,十分快捷方便 使用Arrow需要两步转换操作: 1 ...

  5. 导入PrefixHeader.pch 报错UNknow The type "NSString",等基础类

    进入到项目,在Buid Settings收索Compile Source 把Compile Source As 改成Objective-C问题即可解决.

  6. [LeetCode&Python] Problem 594. Longest Harmonious Subsequence

    We define a harmonious array is an array where the difference between its maximum value and its mini ...

  7. 非root用户安装python3

    1.下载源码 wget -c https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tgz 解压: tar xzf Python-3.7.1.tgz ...

  8. 浅谈get,post,put和delete请求

    get.put.post.delete含义与区别   1.GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的select操作一样,只是用来查询一下数据,不会修改.增加数据,不会影 ...

  9. 653. Two Sum IV - Input is a BST-easy

    我不懂有没有收藏之类的功能,收藏别人的解法. tql,不懂为什么直接比较set里的值,不是两个数sum么 有一些答案都用到了iterator迭代器 http://www.cplusplus.com/r ...

  10. Python3常用函数、方法总结(持续更新…)

    最近刷LeetCode,自己自娱自乐完之后去discussion看大佬们的各种巧妙解法,总是止不住的双击666--加上最近Python3用的比较多(虽然Python实在不推荐跑算法题目,一是运行效率太 ...