Java并发编程学习前期知识下篇 通过上一篇<Java并发编程学习前期知识上篇>我们知道了在Java并发中的可见性是什么?volatile的定义以及JMM的定义.我们先来看看几个大厂真实的面试题: 编辑 ​ 编辑 ​ 编辑 ​ 从上面几个真实的面试问题来看,我们可以看到大厂的面试都会问到并发相关的问题.所以 Java并发,这个无论是面试还是在工作中,并发都是会遇到的.Java并发包JUC(java.util.concurrent)有了解过哪些?并发包实现最重要的是什么?其原理是什么知道吗?何为…
一.初识Concurrent 第一次看见concurrent的使用是在同事写的一个抽取系统代码里,当时这部分代码没有完成,有许多的问题,另一个同事接手了这部分代码的功能开发,由于他没有多线程开发的经验,所以我就一起帮着分析.最开始看到这个时很烦燥啊,因为自己接触java时间很短,连synchronized都不知道怎么用呢,突然发现有这么个复杂的东西.当时就只好开始学习吧,毕竟是使用嘛,第一目的就是了解清楚这玩意的各个类与方法都干嘛用的,然后看了看同事的代码大概也就清楚了.感觉这和大部分人一样,能…
Java编程思想,并发编程学习笔记. 一.基本的线程机制 1.定义任务:Runnable接口 线程可以驱动任务,因此需要一种描述任务的方式,这可以由Runnable接口来提供.要想定义任务,只需实现Runnable接口并编写run方法,使得该任务可以执行你的命令.   class MyTask implements Runnable {    private String mName;     public MyTask(String name) {    mName = name;   }  …
以前特地学过并发编程,但是没怎么学进去,不太喜欢.最近发现,作为一个资深工程师,却没有完整深入系统的学习过,而反是现在的BAT大并发是必须的,感觉甚是惭愧. 故找了一片学习文章,如下,准备集中一段时间来学习并发编程技术 --------------------------------------------------------------------------------------------------------------------------------------------…
一年前由于工作需要从微软技术栈入坑Java,并陆陆续续做了一个Java后台项目,目前在搞Scala+Java混合的后台开发,一直觉得并发编程是所有后台工程师的基本功,所以也学习了小一年Java的并发工具,对整体的并发理解乃至分布式都有一定的提高,所以想和大家分享一下. 我的学习路线 首先说说学习路线,我一开始是直接上手JCIP(Java Concurrency in Practice),发现不是很好懂,把握不了那本书的主线,所以思索着从国内的作者开始先,所以便读了下方腾飞的<Java并发编程的艺…
Java并发编程一直是Java程序员必须懂但又是很难懂的技术内容. 这里不仅仅是指使用简单的多线程编程,或者使用juc的某个类.当然这些都是并发编程的基本知识,除了使用这些工具以外,Java并发编程中涉及到的技术原理十分丰富.为了更好地把并发知识形成一个体系,也鉴于本人没有能力写出这类文章,于是参考几位并发编程专家的博客和书籍,做一个简单的整理. 一:并发基础和多线程 首先需要学习的就是并发的基础知识,什么是并发,为什么要并发,多线程的概念,线程安全的概念等. 然后学会使用Java中的Threa…
转载:https://www.cnblogs.com/dolphin0520/p/3920373.html 写的非常棒,好东西要分享一下 Java并发编程:volatile关键字解析 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字才得以重获生机. volatile关键字虽然从字面上理解起来比较简单,但是要用好不是一件容易的事情.由于volatile关…
有两个系列的博文,交替着可以看看: 1. Java并发编程与技术内幕 http://blog.csdn.net/Evankaka/article/details/51866242 2. [Java并发编程]并发编程大合集 http://blog.csdn.net/ns_code/article/details/17539599 3. 最后,可以再看下 Effective Java…
Java的并发编程是依赖虚拟机内存模型的三个特性实现的: (1).原子性(Atomicity): 原子性是指不可再分的最小操作指令,即单条机器指令,原子性操作任意时刻只能有一个线程,因此是线程安全的. Java内存模型中通过read.load.assign.use.store和write这6个操作保证变量的原子性操作. long和double这两个64位长度的数据类型java虚拟机并没有强制规定他们的read.load.store和write操作的原子性,即所谓的非原子性协定,但是目前的各种商业…
引言:以前只是看过介绍volatile的文章,对其的理解也只是停留在理论的层面上,由于最近在项目当中用到了关于并发方面的技术,所以下定决心深入研究一下java并发方面的知识.网上关于volatile的文章非常多,但是并没有讲解非常详细的文章.(哪位要是有好的资料麻烦共享一份给我!)多数的都是一些理论讲解,没有实际的例子代码,就算有代码的也测试不出效果,总之理论总是与代码不匹配. 后来在我不懈的努力之下总算研究出一些成果,在此分享给大家!如果大家发现有错误的地方欢迎大家指正,谢谢! 在Java线程…
CLH算法实现 CLH队列中的结点QNode中含有一个locked字段,该字段若为true表示该线程需要获取锁,且不释放锁,为false表示线程释放了锁.结点之间是通过隐形的链表相连,之所以叫隐形的链表是因为这些结点之间没有明显的next指针,而是通过myPred所指向的结点的变化情况来影响myNode的行为.CLHLock上还有一个尾指针,始终指向队列的最后一个结点.CLHLock的类图如下所示:       当一个线程需要获取锁时,会创建一个新的QNode,将其中的locked设置为true…
并发编程这方面以前关注得比较少,恶补一下,推荐一个好的网站:并发编程网 - ifeve.com,上面全是各种大牛原创或编译的并发编程文章. 今天先来学习Semaphore(信号量),字面上看,根本不知道这东西是干啥的,借用 并发工具类(三)控制并发线程数的Semaphore一文中的交通红绿信号灯的例子来理解一下: 一条4车道的主干道,假设100米长,每辆车假设占用的长度为10米(考虑到前后车距),也就是说这条道上满负载运行的话,最多只能容纳4*(100/10)=40辆车,如果有120辆车要通过的…
误解一:并发就是多线程 实际上多线程只是并发编程的一种形式,在C#中还有很多更实用.更方便的并发编程技术,包括异步编程.并行编程.TPL 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并发 服务器端的大型程序要响应大量客户端的数据请求,当然要充分考虑并发.但是桌面程序和手机.平板等移动端应用同样需要考虑并发编程,因为它们是直接面向最终用户的,而现在用户对使用体验的要求越来越高.程序必须能随时响应用户的操作,尤其是在后台处理时(读写数据.与服务器通信等),这正是并发编程的目的之一.…
多线程应用中,如果希望一个变量隔离在某个线程内,即:该变量只能由某个线程本身可见,其它线程无法访问,那么ThreadLocal可以很方便的帮你做到这一点. 先来看一下示例: package yjmyzz.test; public class ThreadLocalTest1 { public static class MyRunnable implements Runnable { private ThreadLocal<Integer> threadLocal = new ThreadLoc…
线程安全类:在线程安全类中封装了必要的同步机制,客户端无须进一步采取同步措施 示例:一个无状态的Servlet @ThreadSafe public class StatelessFactorizer implements Servlet{ public void service(ServletRequest req,ServletResponse resp){ BigInteger i = extractFromRequest(req); BigInteger[] factors = fact…
1.并发的意义 现在是一个多核的时代,并发的存在意义就是为了能够充分利用多核计算机的优势,提高程序的运行效率: 2.并发的风险 竞争-----多个线程对内存数据数据进行读写操作时,对数据处理结果的一个竞争.(笔者是这么认为的) 使用以下的例子来说明并发的风险:由于该方法中的value++操作不是原子性的,是分为读->运算->赋值 这3个步骤的. 假如线程A执行了读,正准备开始运算的时候,线程B开始调用这个实例的getNext方法,那么这个时候线程B读取的数据与线程A读取的数据是一样的. 即A获…
主要概念:线程安全性.原子性.原子变量.原子操作.竟态条件.复合操作.加锁机制.重入.活跃性与性能. 1.当多个线程访问某个状态变量并且其中有一个线程执行写入操作时,必须采用同步机制来协同这些线程对变量的访问.Java中的主要同步机制是关键字synchronized,他提供了一种独占的加锁方式. 2.当设计线程安全的类时,良好的面相对象技术.不可修改性.以及明晰的不变性规范都能启动一定的帮助作用. 3.线程安全类的定义:当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替…
随着多核CPU的高速发展,为了充分利用硬件的计算资源,操作系统的并发多任务功能正变得越来越重要,但是CPU在进行计算时,还需要从内存读取输出,并将计算结果存放到内存中,然而由于CPU的运算速度比内存高几个数量级,CPU内的寄存器数量和容量有限,为了不让CPU长时间处于等待内存的空闲状态,在CPU和内存之间引入了速度接近CPU的高速缓存Cache作为CPU和内存之间的缓冲.计算机硬件并发的原理如下: Java虚拟机对并发的支持类似于计算机硬件,java虚拟机的并发支持是通过java虚拟机的内存模型…
1.通过Unsafe类可以分配内存,可以释放内存:类中提供的3个本地方法allocateMemory.reallocateMemory.freeMemory分别用于分配内存,扩充内存和释放内存,与C语言中的3个方法对应.2.可以定位对象某字段的内存位置,也可以修改对象的字段值,即使它是私有的:[java] view plaincopyprint?public native long allocateMemory(long l); public native long reallocateMemo…
1. 多线程场景下尽量使用并发容器代替同步容器 (如ConcurrentHashMap代替同步且基于散列的Map, 遍历操作为主要操作的情况下用CopyOnWriteArrayList代替同步的List) ConcurrentHashMap:分段锁机制,多线程条件下优于HashMap+synchronized的组合方式: CopyOnWriteArrayList: 每次修改时都会创建并重新发布一个新的容器副本,从而实现可变性.容器的迭代器保留一个指向底层基础数组的引用,这个数组当前位于迭代器的起…
重要概念: 1.在设计线程安全类的过程中,需要包含以下三个基本要素: (1)找出构成对象状态的所有变量. (2)找出约束状态变量的不变性条件. (3)建立对象状态的并发访问管理策略. 2.…
ReentrantLock是一个可重入的互斥锁,ReentrantLock由最近成功获取锁,还没有释放的线程所拥有,当锁被另一个线程拥有时,调用lock的线程可以成功获取锁.如果锁已经被当前线程拥有,当前线程会立即返回.此类的构造方法提供一个可选的公平参数 public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(); } 公平与非公平有何区别,所谓公平就是严格按照FIFO顺序获取锁,非…
一. 如果在持有锁时调用某个外部方法,那么将出现活跃性问题.在这个外部方法中可能会获取其他锁(这可能会产生死锁),或者阻塞时间过长,导致其他线程无法及时获得当前被持有的锁.如下代码: public class Taxi { private final Dispatcher dispatcher; private Point location, destination; public Taxi(Dispatcher dispatcher) { this.dispatcher = dispatche…
一.并发容器:ConcurrentHashMap:1.分段锁机制: 任意数量的读取线程可以并发的访问map,执行读取操作的线程和执行写入操作的线程可以并发的访问Map,并且一定数量的写入线程可以并发的修改Map.2.无需再迭代过程中对容器加锁:3.ConcurrentHashMap无法实现对Map加锁已提供独占访问,在HashMap及SynchrogazedMap中,获得Map的锁能防止其他线程访问这个Map; 4.大多数情况下,用ConcurrentHashMap代替同步Map能进一步提高代码…
一.非原子的64位操作: 当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值,这种安全性保证被称为最低安全性.最低安全性适用于绝大多数变量,但存在一个例外:非volatile类型的64位数值变量(double,long),Java内存模型要求,变量的读取和写入操作都必须是原子操作,但对于非volatile型的long,double变量,JVM允许将64位的读操作或写操作分解为两个32位的操作,当读取一个非volatile类型的long…
主要概念:可见性.重排序.失效数据.最低安全性.发布.逸出.线程封闭(Ad-hoc.栈封闭.ThreadLocal类).不变性.Final域.事实不可变对象. 1.在没有同步的情况下,编译器.处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整.在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序进行判断,几乎无法得出正确的结论. 2.在多线程中使用共享且可变的long和double等类型的变量是不安全的,除非用关键字volatile来声明它们,或者用锁来保护他们. 3.加锁的含义不…
创建线程一般有如下几个方式: 1. 通过继承Thread类来创建一个线程: /** * 步骤1:定义一个继承Thread类的子类 * 步骤2:构造子类的一个对象 * 步骤3:启动线程: * */ public class ThreadTest{ public static void main(String[] args) { //构造子类对象 SubThread subThread = new SubThread(); //启动线程 subThread.start(); } } //定义继承Th…
一.需求描述: 将资金从一个账户转移到另一个账户. 二.程序实现: (1)账户类: public class Account { private long account; public Account(String user, long account) { this.account = account; } public Account() { super(); } public long getAccount() { return account; } public void setAcc…
FutureTask是Future和Callable的结合体.传统的代码是这样写的Future f = executor.submit(new Callable()); 然后通过Future来取得计算结果.但是,若开启了多个任务,我们无从知晓哪个任务最先结束,因此,若要实现"当某任务结束时,立刻做一些事情,例如记录日志"这一功能,就需要写一些额外的代码.FutureTask正是为此而存在,他有一个回调函数protected void done(),当任务结束时,该回调函数会被触发.因此…
1. Executor基于生产者-消费者模式,提交任务的操作相当于生产者,执行任务的线程相当于消费者,如果要在程序中实现一个生产者-消费者的设计,最简单的方式通常就是使用Executor 2. Executor的生命周期: 为了解决执行任务的生命周期问题,Executor扩展了ExecutorService接口,添加了一些用于生命周期管理的方法,如下: public interface ExecutorService extends Executor{ void shutdown(); List…