Java并发编程实战笔记1.0

《Java 并发编程的艺术》笔记——第1章 并发编程的挑战 文章目录1.1 上下文切换1.1.1 多线程一定快吗?1.1.2 测试上下文切换次数和时长1.1.3 如何减少上下文切换1.1.4 减少上下文切换实战1.2 死锁1.3 资源限制的挑战1.4 本章小结 声明: 本博客是本人在学习《Java 并发编程的艺术》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。 本博客已标明出处,如有侵权请告知,马上删除。 并发编程的目的是为了让程序运行得更快,但是,并不是启动更多的线程就能让程序最大限度地并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行得更 阅读详情

1.并发编程领域可以抽象成三个核心问题:分工、同步和互斥

分工指的是如何高效地拆解任务并分配给线程,而同步指的是线程之间如何协作,互斥则是保证同一时刻只允许一个线程访问共享资源。

2.并发编程领域问题的产生原因:

源头之一:缓存导致的可见性问题

    一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性。

源头之二:线程切换带来的原子性问题

    我们把一个或者多个操作在CPU执行的过程中不被中断的特性称为原子性。

源头之三:编译优化带来的有序性问题

    编译器为了优化性能,有时候会改变程序中语句的先后顺序,编译器调整了语句的顺序,大多数情况下不影响程序的最终结果。不过有时候编译器及解释器的优化可能导致意想不到的 Bug。

缓存导致的可见性问题,线程切换带来的原子性问题,编译优化带来的有序性问题,其实缓存、线程、编译优化的目的和我们写并发程序的目的是相同的,都是提高程序性能。但是技术在解决一个问题的同时,必然会带来另外一个问题,所以在采用一项技术的同时,一定要
清楚它带来的问题是什么,以及如何规避。

解决可见性、有序性合理的方案应该是按需禁用缓存以及编译优化。解决原子性问题需要互斥锁。

3.死锁

死锁的定义是:一组互相竞争资源的线程因互相等待,导致“永久”阻塞的现象。
只有以下这四个条件都发生时才会出现死锁:
    互斥,共享资源 X 和 Y 只能被一个线程占用;
    占有且等待,线程 T1 已经取得共享资源 X,在等待共享资源 Y 的时候,不释放共享资源 X;
    不可抢占,其他线程不能强行抢占线程 T1 占有的资源;
    循环等待,线程 T1 等待线程 T2 占有的资源,线程 T2 等待线程 T1 占有的资源,就是循环等待。

反过来分析,也就是说只要我们破坏其中一个,就可以成功避免死锁的发生。其中,互斥这个条件我们没有办法破坏,因为我们用锁为的就是互斥。不过其他三个条件都是有办法破坏掉的,到底如何做呢?对于“占用且等待”这个条件,我们可以一次性申请所有的资源,这样
就不存在等待了。对于“不可抢占”这个条件,占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源,这样不可抢占这个条件就破坏掉了。对于“循环等待”这个条件,可以靠按序申请资源来预防。所谓按序申请,是指资源是有线性顺序的,申请的时候可以先申请资源序号小的,再申请资源序号大的,这样线性化后自然就不存在循环了。

4.等待-通知机制

synchronized用法:


class Allocator {
  private List<Object> als;
  // 一次性申请所有资源
  synchronized void apply(bject from, Object to){
    // 经典写法
    while(als.contains(from) ||als.contains(to)){
      try{
        wait();
      }catch(Exception e){
      }   
    } 
    als.add(from);
    als.add(to);  
  }
  // 归还资源
  synchronized void free(
    Object from, Object to){
    als.remove(from);
    als.remove(to);
    notifyAll();
  }
}

关于notify() 和notifyAll():
    notify() 是会随机地通知等待队列中的一个线程,而 notifyAll() 会通知等待队列中的所有线程。从感觉上来讲,应该是notify()更好一些,因为即便通知所有线程,也只有一个线程能够进入临界区。但那所谓的感觉往往都蕴藏着风险,实际上使用notify()也很有风险,它的风险在于可能导致某些线程永远不会被通知到。
    除非经过深思熟虑,否则尽量使用notifyAll()。那什么时候可以使用 notify() 呢?需要满足以下三个条件:
    1.所有等待线程拥有相同的等待条件;
    2.所有等待线程被唤醒后,执行相同的操作;
    3.只需要唤醒一个线程。

lock用法:


public class BlockedQueue<T>{
  final Lock lock = new ReentrantLock();
  // 条件变量:队列不满  
  final Condition notFull = lock.newCondition();
  // 条件变量:队列不空  
  final Condition notEmpty = lock.newCondition();

  // 入队
  void enq(T x) {
    lock.lock();
    try {
      while (队列已满){
        // 等待队列不满 
        notFull.await();
      }  
      // 省略入队操作...
      //入队后,通知可出队
      notEmpty.signal();
    }finally {
      lock.unlock();
    }
  }
  // 出队
  void deq(){
    lock.lock();
    try {
      while (队列已空){
        // 等待队列不空
        notEmpty.await();
      }
      // 省略出队操作...
      //出队后,通知可入队
      notFull.signal();
    }finally {
      lock.unlock();
    }  
  }
}

5.创建多少线程合适?

对于 CPU 密集型的计算场景,在工程上,线程的数量一般会设置为“CPU核数+1”,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证 CPU 的利用率。
对于 I/O 密集型的计算场景,最佳的线程数是与程序中CPU计算和I/O操作的耗时比相关的,我们可以总结出这样一个公式:
    最佳线程数 =CPU 核数 * [ 1 +(I/O 耗时 / CPU 耗时)]

Java 并发编程 理论+实战,带你深入浅出Java并发编程 阅读详情

相关推荐

《Java并发编程艺术》源码解析与实战

htmltable {th, td {th {pre {简介:《Java并发编程艺术》是Java开发者的宝贵资源,本书配套源码包含了书中所有实例和示例,用于加深对并发编程概念的理解与实践。源码包中包含详细的章节源代码、测试用例以及相关材料。

weixin_31688273的博客 914

限时!阿里巴巴泄露内部Java成长笔记,你以为和他们的差距只有一点?

前言 关于技术人如何成长的问题,一直以来都备受关注,因为程序员职业发展很快,即使是相同起点的人,经过几年的工作或学习,会迅速拉开极大的差距,所以技术人保持学习,提升自己,才能够扛得住不断上赶的后浪,也不至于被“拍死”在沙滩上。 近日,经过一朋友的透露,Alibaba也首发了一份限量的“Java成长笔记”,里面记载的知识点非常齐全,看完之后才知道,差距真的不止一点点! Java成长笔记主要是将Java程序员按照年限来进行分层,清晰的标注着Java程序员应该按照怎样的路线来提升自己,需要去学习哪些技术点。

文章中资料均可获取,有需要请添加yunduoa2019即可 198

手把手教你用Python实现最简单的语义通信(Sem Comm)Demo

本文通过Python和PyTorch,手把手教你构建一个基于深度学习的语义通信(Semantic Communication)Demo。该Demo使用自编码器架构,从MNIST图像中提取低维语义特征进行传输与重建,实现了从“传输比特”到“传递含义”的跨越,并探讨了其效率优势与鲁棒性。

weixin_29080843的博客 246

Alibaba首发的《Java技术成长笔记》,渴望提升自己的程序员的必备宝典!

微服务架构(RPC+SpringBoot+SpringCloud Netflix+SpringCloud Alibaba+docker+k8s)JVM深度剖析(理解运行时数据区+堆外内存解读+JDK+内存泄漏问题排查+Arthas+GC算法和垃圾回收器+类加载机制等)高效存储(Redis+mongoDB+MySQL高可用+Mycat+Sharing-Sphere)并发编程进阶(并发工具类实战+CAS+显示锁解析+线程池内部机制+性能优化)数据库(调优+事务+锁+集群+主从+缓存等)3.SSM从入门到精通。

2401_89740586的博客 345

MYSQL、ORACLE、PostgreSQL数据库对象层次及权限管理对比

本文为出于自己扩展、比较、图形化的思维路径自行总结归纳,可能有些细节不太准确,欢迎指正。MySQL、Oracle、PostgreSQL关系型数据库都有管理员用户、用户、权限管理、表函数索引等数据库对象,schema。但在数据库对象隶属层次上有差异和相同的地方。

rachel_2016的博客 1490

团子杂记:SAP收入确认工具RAR(Revenue Recognition&Reporting)在新收入准则下的应用

SAP收入确认工具RAR知识分享

Lucas1211的博客 4284

Java写入文件换行

Java核心架构笔记大致如下 0~1年: Java基础(基本语法、面向对象、继承、多态、接口和抽象类、异常、内部类、集合、泛型、反射、I/O等) Web编程(Servlet+MySQL数据库+商品管理系统实战) SSM框架入门到精通(Spring+SpringMVC+Mybatis+SSM商品管理系统实战) SpringBoot(SpringBoot+SpringBoot商品管理系统实战) 1~3年: JVM深度进阶(JVM内存区域+JVM运行时内存+垃圾回收与算法+JAVA 四种引用类型+GC分代收

imtokenmax众筹 966

(南京观海微电子)——TCON介绍

TCON又称:逻辑板,控制板,在液晶电视里的作用和CRT中的视放板相当,但有本质的区别,逻辑板不是一个纯粹的信号放大器,它输入是LVDS格式信号,而不是RGB。逻辑板的作用是把数字板送来的LVDS或TTL图像数据信号,时钟信号进行处理移位寄存器存储将图像数据信号,时钟信号转换成屏能够识别的控制信号行列信号RSDS控制屏内的MOSFET管工作而控制液晶分子的扭曲度。目前国内主要的TCON板生产商有视显光电。传统TCON的布局主要分为以下两种:X+C分离式和X+C一体式。

m0_75095200的博客 3834

《Java 并发编程实战》学习笔记一

多核时代每颗 CPU 都有自己的缓存,这时 CPU 缓存(三级缓存)与内存的数据一致性就容易出现问题了,当多个线程在不同的 CPU 上执行时,这些线程操作的是不同的 CPU 缓存。比如,线程 A 操作的是 CPU-1 上的缓存,而线程 B 操作的是 CPU-2 上的缓存,很明显,这个时候线程 A 对变量 V 的操作对于线程 B 而言就不具备可见性了。:高级语言里一条语句往往需要多条 CPU 指令完成,例如count += 1这句代码,至少需要三条 CPU 指令。

yibushao的博客 1152

factory机制-重载(一)

这里写自定义目录标题1.SystemVerilog对重载的支持2.对约束的重载3.factory 机制式的重载4.重载的方式和种类5.factory机制的调试 1.SystemVerilog对重载的支持 SystemVerilog是一种面向对象的语言。面向对象语言都有一大特征:重载。当在父类中定义一个函数/任务时,如果将其设置为virtual类型,那么就可以在子类中重载这个函数或任务。 重载的最大优势是使得一个子类的指针以父类的类型传递时,其表现的行为依然是子类的行为。 2.对约束的重载 在测试一个DUT时

sinat_41774721的博客 2960

科研项目数据抓取:Python爬虫实现与分析

本文详细介绍了如何使用Python爬虫抓取科研项目的数据,涵盖了从目标数据源选择到数据存储与分析的整个过程。通过使用。

2201_76125261的博客 1710

Java并发编程实战笔记

Java并发编程实战笔记

daweias的博客 443

29、Power BI 中行级安全(RLS)的实现与应用

本文详细介绍了在Power BI中实现行级安全(RLS)的方法,包括静态RLS和动态RLS的实现流程、适用场景及对比分析。通过具体业务场景,展示了如何创建安全角色、定义规则、验证角色、发布模型以及分配成员。此外,还探讨了更复杂的动态RLS场景,如基于父子层次结构的数据访问控制和从外部源获取用户信息的实现方式。文章最后总结了最佳实践建议及未来发展趋势,为企业在Power BI中高效、安全地实施数据访问控制提供了全面指导。

terraform7cloud的博客 195

【极客时间】《Java并发编程实战》学习笔记

【极客时间】《Java并发编程实战》学习笔记

Mr.Cui的Java学习之路 2649

【漏洞复现】用友NC-Cloud-反序列化-ResourceManagerServlet

NC Cloud是用友公司推出的大型企业数字化平台。支持公有云、混合云、专属云的灵活部署模式。NC Cloud完全基于云原生架构,技术先进、性能稳定、自主安全可控,支撑大中型以及超大型集团企业N层多site混合云部署方案,支持整个系统高可用、弹性扩展、双/多活,以及快速灾备恢复能力等。用友-NC-Cloud ResourceManagerServlet 接口存在反序列化漏洞,使得攻击者可以通过构造特定的请求远程执行恶意代码。此漏洞可能导致攻击者获取系统权限、执行任意命令,严重威胁系统的机密性和完整性。

漏洞复现 1366

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java并发编程实战(1)

该系列文章是博主学习笔记,禁止转载,读书交流群:946541246 · 文章目录Java并发编程实战一二章学习概念无状态竟态条件不变性条件相互约束的变量要在一个原子操作中进行复合操作 Java并发编程实战一二章学习 概念 无状态 既不包含任何域,也不包含任何对其他类中域的引用。 无状态一定是线程安全的 例如 @ThreadSafe public class StatelessFactorizer...

谢耀眼 467

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Java并发编程实战读书笔记

Java并发编程实战读书笔记并发编程的挑战上下文切换如何减少上下文切换如何避免死锁Java并发机制的底层实现原理volatile的使用violate如何保证可见性?lock前缀的作用:synchronized的实现原理与应用 本文记录了阅读该书中本人认为比较有收获,比较重要的知识点。其中有一些内容加了一些自己的理解。 并发编程的挑战 上下文切换 上下文切换发生在同一个cpu中,cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切

qq_39863093的博客 1025

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

《JAVA并发编程的艺术》之 Java并发编程实战

《JAVA并发编程的艺术》之 Java并发编程实战 文章目录《JAVA并发编程的艺术》之 Java并发编程实战生产者和消费者模式生产者消费者模式实战多生产者和多消费者场景线程池与生产消费者模式线上问题定位性能测试查看网络流量。查看系统平均负载。查看系统内存情况。查看CPU的利用率。异步任务池 当你在进行并发编程时,看着程序的执行速度在自己的优化下运行得越来越快,你会觉得越来越有成就感,这就是并发编程的魅力。但与此同时,并发编程产生的问题和风险可能也 会随之而来。本章先介绍几个并发编程的实战案例,然后再介绍如

weixin_44019182的博客 1319

Java并发编程:深入探索与实战案例

Java并发编程是一个复杂而强大的领域,它提供了多种工具和技术来应对多线程环境下的挑战。从基础的到高级的 ` LockAtomic `类,再到线程池和并发集合,Java为开发者提供了丰富的选择。通过理解这些工具的工作原理,并结合实际场景进行应用,我们可以构建出高性能、可扩展的并发应用程序。本文介绍的实战案例,展示了如何将这些知识应用于构建一个简单但高效的Web服务器,希望对读者有所启发。

运维人生 1462

Java并发编程实战(2)

该系列文章是博主学习笔记,禁止转载,读书交流群:946541246 文章目录Java并发编程实战三四章学习加锁与可见性volatile Java并发编程实战三四章学习 加锁与可见性 锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果 当线程A执行某个同步代码时,线程B随后进入由同一个锁保护的同步代码块,在这种情况下可以保证,在锁被释放钱,A看到的变量值在B获得锁后同样可以由B看到。...

谢耀眼 1008

Java 并发编程实战

1. 可见性、原子性和有序性问题:并发编程 Bug 的源头 在并发编程中,常常会遇到由于线程之间共享数据而导致的问题,主要体现在可见性、原子性和有序性上。让我们通过一些代码示例来深入理解这些问题。 可见性问题 public class VisibilityTest { private static boolean flag = false; public static void main(String[] args) throws InterruptedException {

wolf23151269的博客 1664

Java并发编程实战.pdf资源介绍:Java并发编程领域的权威指南

Java并发编程实战.pdf资源介绍:Java并发编程领域的权威指南 【下载地址】Java并发编程实战.pdf资源介绍 《Java并发编程实战》是Java并发编程领域的经典著作,全面涵盖了线程管理、并发集合、同步器、锁、线程安全等核心内容。本书结构清晰,实例丰富,适合Java初学者和经验丰富的开发者。通过深入学习,你将掌...

gitblog_06715的博客 1188

Java并发编程实战基础概要

Java线程之间的通信由Java内存模型(JMM)控制。JMM定义了线程和主内存之间的抽象关系在内存里,Java内存模型规定了所有的变量都存储在主内存(物理内存)中,每条线程还有自己的工作内存,线程对变量的所有操作都必须在工作内存中进行。不同的线程无法访问其他线程的工作内存里的内容。我们可以使用下图来表示在逻辑上线程、主内存、工作内存的三者交互关系。额外的延伸知识,从JVM的角度来看java运行时的内存区域,来对应我们Java内存模型前面我们都理解了缓存导致了可见性问题,编译优化导致了有序性问题。.....

C. 785

Java并发编程实战极客时间

我整理的一些关于【Java】的项目学习资料(附讲解~~)和大家一起分享、学习一下:https://d.51cto.com/bLN8S1Java并发编程实战指南 在当今的软件开发中,掌握并发编程是一项必不可少的技能。为了帮助你实现“Java并发编程实战”的目标,我将为你提供一个详细的步骤指南。本文将从基本概念开始,引导你逐...

weixin_35178718的博客 305
上一篇: Oracle:ROWNUM介绍和分页使用
下一篇: Java并发编程实战笔记2.0
过河的小卒子
博客等级 码龄10年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值