
Java并发编程实战
学者们对并发这个概念一定不会陌生,但是写出高并发的程序还是有一定难度的,现在会逐步深入讲解Java并发的底层概念和程序实现,从而使大家真正认识到Java高并发的色彩
嗯哼唉、
后端、云计算、大数据
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
一不小心就死锁了——怎么办?
上一篇文章中,用Account.class做互斥锁来解决银行中的转账问题,虽然不存在并发问题但是所有操操作都是串行的,其实在现实世界里是可以并行的,使用串行操作导致性能太差。。互联网支付盛行的现在,如果所有的交易操作都是串行的那么性能完全不能接受。。下面尝试将性能进行优化。。向现实世界要答案现实世界里,账户转账操作是支持并发的而且绝对是真正的并行,银行所有窗口都可以做转账。只要能仿照现实世...原创 2019-08-25 20:31:50 · 277 阅读 · 0 评论 -
互斥锁(下):如何用一把锁保护多个资源?
上一篇文章中提到一把锁可以保护多个资源,受保护资源和锁之间合理的关联关系应该是N:1的关系,阐述了如何正确保护一个资源,但是如何正确保护多个资源没说。最后说到两把锁保护两个资源,一个this一个所属类,但是不互斥会造成并发问题。。。产生问题最主要的原因是this对象和所属类存在必然关联关系。当我们要保护多个资源时,首先要区分这些资源是否存在关联关系。。。保护没有关联关系的多个资源现实世界中...原创 2019-08-24 21:22:09 · 420 阅读 · 0 评论 -
互斥锁(上):解决原子性问题
在前面的文章中提到,一个或者多个操作在CPU执行的过程中不被中断的特性叫做“原子性”。前一篇文章中说到应该如何解决有序性和可见性的问题,就是借助volatile,final,synchronized等关键字,或者Happens-Before的六大原则来解决。原子性问题到底该如何解决???原子性问题的源头是线程切换,如果能够禁用线程切换就能解决这个问题。。操作系统做线程切换是依赖CPU中断的,...原创 2019-08-24 20:16:31 · 214 阅读 · 0 评论 -
Java内存模型:看Java如何解决可见性和有序性问题
专栏的上一篇文章简单介绍了一下导致原子性、可见性、有序性的很容易看到的问题(可能是违背我们的意愿的出现),现在来说一下如何解决其中的可见性和有序性导致的问题,引出了今天的问题——Java内存模型。Java内存模型,不要和JVM内存模型混淆,但是二者确实是有联系的,Java内存模型更倾向于Java并发方面的知识,JVM内存模型在Java方面全都会涉及的。。。什么是Java内存模型之前提到过vo...原创 2019-08-22 12:06:03 · 209 阅读 · 0 评论 -
可见性、原子性和有序性问题:并发编程Bug的源头
可见性、原子性、有序性,往往这些多线程的三要素都会出现在高级编程知识中。并且涉及到了很多操作系统的知识,如果多操作系统不是很熟悉的话,就会出现很多的问题。。。多线程编程经常会出现一些玄学问题,所以编写正确的并发程序是一件极困难的事情,今天就重点来聊聊这些Bug的源头。。。并发程序幕后的故事这些年,我们的CPU、内存、I/O设备都在不断迭代,不断朝着更快的方向努力。但是还是有一个核心矛盾一直存...原创 2019-08-21 21:57:18 · 290 阅读 · 0 评论 -
Executors与线程池:如何创建正确的线程池
在很多公司的面试中,线程池的题目往往都是比较多且较难的,并且线程相关的对象和其他业务API是不相同的,区别在于一个直接操作操作系统,使用的是操作系统相关的API,一个单纯只占用内存。从Java核心技术专栏线程中的相关知识我们可以知道,线程产生与销毁都会消耗一定的性能,因此要避免频繁的创建与销毁。因此解决这个问题的关键就是创建线程池。概述线程池的需求很普遍,从一般使用的池化角度来看:当需要资...原创 2019-07-24 12:51:53 · 538 阅读 · 0 评论 -
并发包中的ConcurrentLinkedQueue和LinkedBlockingQueue的区别
初步了解有的时候将并发包下面的所有容器习惯叫作并发容器,但是严格来讲类似ConcurrentLinkedQueue这种“Concurrent”容器才是真正代表并发。两种的区别:Concurrent类型基于lock-free,在日常的多线程访问场景,一般可以提供较高吞吐量。而LinkedBlockingQueue内部则是基于锁,并提供了BlockingQueue的等待性方法。不知道大家...原创 2019-07-23 23:07:45 · 370 阅读 · 0 评论 -
什么情况下Java程序会产生死锁?如何定位、修复?
初步了解:死锁是一种特定的程序状态,在实体之间,由于循环依赖导致彼此一直处于等待之中,没有任何个体可以继续前进。死锁不仅仅是在线程之间会发生,存在资源独占的进程之间同样也可能出现死锁。通常来说,大多都是聚集在多线程场景中的死锁,指两个或多个线程之间,由于互相有对方需要的锁,而永久处于阻塞状态。下图理解基本的死锁:定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位互相之间的依...原创 2019-07-23 01:27:07 · 641 阅读 · 0 评论 -
一个线程两次调用start()方法会出现什么情况?
问题的引入: 一个线程两次调用start()方法会出现什么情况?谈谈线程的生命周期和状态转移。初步了解Java线程是不允许启动两次的,第二次调用必然会抛出IllegalThreadStateException,这是一种运行时异常,多次调用start被认为是编程错误。关于线程生命周期的不同状态,在Java 5之后线程状态被明确定义在其公共内部枚举类型java.lang.Thread.State...原创 2019-07-22 22:54:16 · 540 阅读 · 0 评论 -
synchronized底层如何实现?什么是锁的升级、降级?
初步了解:先来简单复习一下之前的知识,synchronized代码块是由一对儿monitorenter/monitorexit指令实现的,Monitor对象是同步的基本实现单元。在Java6之前,Monitor的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户状态到内核状态的切换,所以同步操作是一个无差别的重量级操作。现代的(Oracle)JDK中,JVM对此进行了很大的改进,提供了三...原创 2019-07-22 13:13:23 · 507 阅读 · 0 评论 -
synchronized和ReentrantLock的区别
初步了解:synchronized是Java内建的同步机制,所以也有人称其为Intrinsic Locking,它提供了互斥的语义和可见性,当一个线程已经获取当前锁时,其他试图获取的线程只能等待或者阻塞在那里。在Java 5以前, synchronized是仅有的同步手段,在代码中, synchronized可以用来修饰方法,也可以使用在特定的代码块儿上,本质上synchronized方法等...原创 2019-07-21 12:06:55 · 232 阅读 · 0 评论 -
ConcurrentHashMap如何实现高效的线程安全
此前已经介绍了Java集合框架的典型,并且也分析了比较流行的Map实现方法HashMap,让大家进一步的了解了使用方法和底层原理,并且简单讲述了线程方面的问题,此文章将主要围绕线程,亦或是并发的角度去介绍。之前所介绍大多数都是线程不安全的,但也有像HashTable这样安全,但是性能很差,成本很高的,所以Java内部也提供了并发包,为高度并发需求提供了更加全面的工具支持。那么,应该如何保证线程...原创 2019-07-11 21:12:06 · 793 阅读 · 0 评论 -
"等待-通知"机制优化循环等待
专栏的上一篇文章介绍过在破坏占用且等待条件的时候,如果转出和转入账本不满足同时在文件架上时就要使用循环的方式来循环等待,核心代码如下: // ⼀次性申请转出账⼾和转⼊账⼾, 直到成功 while(!actr.apply(this, target)) ;如果apply()操作耗时非常短并发冲突量也不是很大,还是可以使用的,因为循环几次或者几十次就能一次性获取转出账户和转入账户了。但是如果...原创 2019-08-26 19:33:45 · 301 阅读 · 0 评论