
Java并发编程
文章平均质量分 74
咖啡Q伴侣
纸上得来终觉浅,绝知此事要躬行! 代码虐我千百遍,我视代码如初恋!
展开
-
第一篇:可重入内置锁
每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁或监视器锁。线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。 当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。然而,由于内置锁是可重入的,因此如果摸个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。“重入”意味着获原创 2017-08-17 13:37:46 · 253 阅读 · 0 评论 -
第二十一篇:并发新特性—阻塞队列和阻塞栈(含代码)
阻塞队列 阻塞队列是Java 5并发新特性中的内容,阻塞队列的接口是Java.util.concurrent.BlockingQueue,它有多个实现类:ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等,用法大同小异,具体可查看JDK文档,这里简单举例看下Ar原创 2017-08-22 09:40:19 · 231 阅读 · 0 评论 -
第二十二篇:并发新特性—障碍器CyclicBarrier(含代码)
CyclicBarrier(又叫障碍器)同样是Java 5中加入的新特性,使用时需要导入Java.util.concurrent.CylicBarrier。它适用于这样一种情况:你希望创建一组任务,它们并发地执行工作,另外的一个任务在这一组任务并发执行结束前一直阻塞等待,直到该组任务全部执行结束,这个任务才得以执行。这非常像CountDownLatch,只是CountDownLatch是只触发一次原创 2017-08-22 09:41:22 · 227 阅读 · 0 评论 -
第二十三篇:并发新特性—信号量Semaphore(含代码)
在操作系统中,信号量是个很重要的概念,它在控制进程间的协作方面有着非常重要的作用,通过对信号量的不同操作,可以分别实现进程间的互斥与同步。当然它也可以用于多线程的控制,我们完全可以通过使用信号量来自定义实现类似Java中的synchronized、wait、notify机制。 Java并发包中的信号量Semaphore实际上是一个功能完毕的计数信号量,从概念上讲,它维护了一个许可集合,对原创 2017-08-22 09:42:20 · 212 阅读 · 0 评论 -
第五篇:volatile变量修饰符—意料之外的问题(含代码)
volatile用处说明 在JDK1.2之前,Java的内存模型实现总是从主存(即共享内存)读取变量,是不需要进行特别的注意的。而随着JVM的成熟和优化,现在在多线程环境下volatile关键字的使用变得非常重要。在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一原创 2017-08-17 14:36:43 · 296 阅读 · 0 评论 -
第十五篇:并发编程中实现内存可见的两种方法比较:加锁和volatile变量
在http://blog.youkuaiyun.com/u012426327/article/details/77469701这篇博文中,讲述了通过同步实现内存可见性的方法,在http://blog.youkuaiyun.com/u012426327/article/details/77328001这篇博文中,讲述了通过volatile变量实现内存可见性的方法,这里比较下二者的区别。 1、volatile原创 2017-08-22 09:30:01 · 228 阅读 · 0 评论 -
第十七篇:深入Java内存模型—内存操作规则总结
主内存与工作内存 Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。此处的变量主要是指共享变量,存在竞争问题的变量。Java内存模型规定所有的变量都存储在主内存中,而每条线程还有自己的工作内存,线程的工作内存中保存了该线程使用到的变量的主内存副本拷贝,线程对变量的所有操作(读取、赋值等)都必须在工作内存中进行,而不能直原创 2017-08-22 09:34:04 · 227 阅读 · 0 评论 -
第十九篇:并发新特性—Executor框架与线程池(含代码)
Executor框架简介 在Java 5之后,并发编程引入了一堆新的启动、调度和管理线程的API。Executor框架便是java 5中引入的,其内部使用了线程池机制,它在Java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易原创 2017-08-22 09:38:18 · 261 阅读 · 0 评论 -
并发编程汇总
不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!JAVA基础学习线路图可重入内置锁线程中断(含代码)线程挂起、恢复与终止的正确方法(含代码)守护线程与线程阻塞的四种情况volatile变量修饰符—意料之外的问题(含代码)Runnable和Thread实现多线程的区别(含代码)使用synchronized获取互斥锁的几点说原创 2017-08-28 09:47:50 · 484 阅读 · 0 评论 -
并发编程1:全面认识 Thread
读完本文你将了解到:线程简介线程创建的三种方式实现 Runnable 接口继承 Thread重写其 run 方法实现 Callable 接口重写 call 方法用 FutureTask 获得结果线程的基本属性优先级守护线程线程的生命周期线程的关键方法ThreadsleepObjectwaitThreadyieldThreadjoin线转载 2017-08-28 10:20:21 · 256 阅读 · 0 评论 -
并发编程2:认识并发编程的利与弊
读完本文你将了解:多线程的优点1提高资源利用率2响应更快多线程的缺点1增加资源消耗2上下文切换的开销3设计编码测试的复杂度增加Java 内存模型与 CPU 内存简介Java 中的堆Java 中的栈计算机中的内存寄存器缓存多线程可能出现的问题竞态条件与临界区内存可见性总结35 追加Thanks从上篇文转载 2017-08-28 10:33:26 · 242 阅读 · 0 评论 -
并发编程3:线程池的使用与执行流程
并发编程系列的文章酝酿好久了,但由于没有时间和毅力去写那么多练习 demo,很多文章写了一半就停止了。在写某一系列的过程中总有其他想写的内容蹦出来,想忍住不分散精力太难了,所以我很佩服那些能专心研究、总结一个专题的人,他们是有毅力的人!关于学习的方式我也困惑过很久,究竟是知识体系驱动还是项目驱动比较好呢?知识体系驱动即一条道走到头的学习(逮住某个专题深入研究,直到整个过一遍转载 2017-08-28 10:47:03 · 296 阅读 · 0 评论 -
并发编程4:Java 阻塞队列源码分析(上)
上篇文章 并发编程3:线程池的使用与执行流程 中我们了解到,线程池中需要使用阻塞队列来保存待执行的任务。这篇文章我们来详细了解下 Java 中的阻塞队列究竟是什么。读完你将了解:什么是阻塞队列七种阻塞队列的前三种ArrayBlockingQueue看它的主要属性构造函数四种添加元素方法的实现四种获取元素的实现LinkedBlockingQueue原创 2017-08-28 10:52:33 · 367 阅读 · 0 评论 -
并发编程5:Java 阻塞队列源码分析(下)
上一篇 并发编程4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文章来了解剩下的四种阻塞队列。读完本文你将了解:七种阻塞队列的后四种DelayQueueDelayQueue的关键属性实现Delayed接口延时阻塞队列如何实转载 2017-08-28 10:58:01 · 302 阅读 · 0 评论 -
第二十篇:并发新特性—Lock锁和条件变量(含代码)
简单使用Lock锁 Java 5中引入了新的锁机制——Java.util.concurrent.locks中的显式的互斥锁:Lock接口,它提供了比synchronized更加广泛的锁定操作。Lock接口有3个实现它的类:ReentrantLock、ReetrantReadWriteLock.ReadLock和ReetrantReadWriteLock.WriteLock,即重入锁、读锁原创 2017-08-22 09:39:23 · 610 阅读 · 0 评论 -
第六篇:Runnable和Thread实现多线程的区别(含代码)
Java中实现多线程有两种方法:继承Thread类、实现Runnable接口,在程序开发中只要是多线程,肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下优势: 1、可以避免由于Java的单继承特性而带来的局限; 2、增强程序的健壮性,代码能够被多个线程共享,代码与数据是独立的; 3、适合多个相同程序代码的线程区处理同一资原创 2017-08-22 09:17:48 · 227 阅读 · 0 评论 -
第二篇:线程中断(含代码)
使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是,如果只是单纯的调用interrupt()方法,线程并没有实际被中断,会继续往下执行。 下面一段代码演示了休眠线程的中断:[java] view原创 2017-08-17 13:52:36 · 291 阅读 · 0 评论 -
第三篇:线程挂起、恢复与终止的正确方法(含代码)
挂起和恢复线程 Thread 的API中包含两个被淘汰的方法,它们用于临时挂起和重启某个线程,这些方法已经被淘汰,因为它们是不安全的,不稳定的。如果在不合适的时候挂起线程(比如,锁定共享资源时),此时便可能会发生死锁条件——其他线程在等待该线程释放锁,但该线程却被挂起了,便会发生死锁。另外,在长时间计算期间挂起线程也可能导致问题。 下面的代码演示了通过休眠来延缓运行,模拟长时间原创 2017-08-17 13:54:57 · 1349 阅读 · 0 评论 -
第四篇:守护线程与线程阻塞的四种情况
守护线程 Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程) 用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通、非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程。当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出原创 2017-08-17 13:57:25 · 303 阅读 · 0 评论 -
第九篇:死锁(含代码)
当线程需要同时持有多个锁时,有可能产生死锁。考虑如下情形: 线程A当前持有互斥所锁lock1,线程B当前持有互斥锁lock2。接下来,当线程A仍然持有lock1时,它试图获取lock2,因为线程B正持有lock2,因此线程A会阻塞等待线程B对lock2的释放。如果此时线程B在持有lock2的时候,也在试图获取lock1,因为线程A正持有lock1,因此线程B会阻塞等待A对lock1的原创 2017-08-22 09:22:41 · 240 阅读 · 0 评论 -
第十八篇:第五篇中volatile意外问题的正确分析解答(含代码)
一文中遗留了一个问题,就是volatile只修饰了missedIt变量,而没修饰value变量,但是在线程读取value的值的时候,也读到的是最新的数据。但是在网上查了很多资料都无果,看来很多人对volatile的规则并不是太清晰,或者说只停留在很表面的层次,一知半解。 这两天看《深入Java虚拟机——JVM高级特性与最佳实践》第12章:Java内存模型与线程,并在网上查阅了Java内存原创 2017-08-22 09:36:26 · 238 阅读 · 0 评论 -
第十四篇:图文讲述同步的另一个重要功能:内存可见性
加锁(synchronized同步)的功能不仅仅局限于互斥行为,同时还存在另外一个重要的方面:内存可见性。我们不仅希望防止某个线程正在使用对象状态而另一个线程在同时修改该状态,而且还希望确保当一个线程修改了对象状态后,其他线程能够看到该变化。而线程的同步恰恰也能够实现这一点。 内置锁可以用于确保某个线程以一种可预测的方式来查看另一个线程的执行结果。为了确保所有的线程都能看到共享变量的最原创 2017-08-22 09:28:01 · 218 阅读 · 0 评论 -
第十三篇:生产者—消费者模型(含代码)
生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。 这里实现如下情况的生产--消费模型: 生产者不断交替地生产两组数据“姓名--1 --> 内容--1”,“姓名--2--> 内容--2”,消费者不断交替地取得这两组数据,这里的“姓名--1”和“姓名--2”模拟为数据的名称,“内容--1 ”和“内容原创 2017-08-22 09:26:47 · 338 阅读 · 0 评论 -
第十二篇:线程间通信中notifyAll造成的早期通知问题(含代码)
如果线程在等待时接到通知,但线程等待的条件还不满足,此时,线程接到的就是早期通知,如果条件满足的时间很短,但很快又改变了,而变得不再满足,这时也将发生早期通知。这种现象听起来很奇怪,下面通过一个示例程序来说明问题。 很简单,两个线程等待删除List中的元素,同时另外一个线程正要向其中添加项目。代码如下:[java] view plain copy原创 2017-08-22 09:25:50 · 272 阅读 · 0 评论 -
第十一篇:线程间通信中notify通知的遗漏(含代码)
notify通知的遗漏很容易理解,即threadA还没开始wait的时候,threadB已经notify了,这样,threadB通知是没有任何响应的,当threadB退出synchronized代码块后,threadA再开始wait,便会一直阻塞等待,直到被别的线程打断。 遗漏通知的代码 下面给出一段代码演示通知是如何遗漏的,如下:[java] view pl原创 2017-08-22 09:24:51 · 296 阅读 · 0 评论 -
第十篇:使用wait/notify/notifyAll实现线程间通信的几点重要说明
在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信。在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调用notify()方法或notifyAll()方法),在线程中调用notify()方法或notifyAll()方法,将通知其他线程从wait()方法处返回。 Object是所有类原创 2017-08-22 09:23:34 · 299 阅读 · 0 评论 -
第八篇:多线程环境中安全使用集合API(含代码)
在集合API中,最初设计的Vector和Hashtable是多线程安全的。例如:对于Vector来说,用来添加和删除元素的方法是同步的。如果只有一个线程与Vector的实例交互,那么,要求获取和释放对象锁便是一种浪费,另外在不必要的时候如果滥用同步化,也有可能会带来死锁。因此,对于更改集合内容的方法,没有一个是同步化的。集合本质上是非多线程安全的,当多个线程与集合交互时,为了使它多线程安全,必须采原创 2017-08-22 09:20:42 · 260 阅读 · 0 评论 -
第七篇:使用synchronized获取互斥锁的几点说明
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确保在某一时刻,方法内只允许有一个线程。 采用synchronized修饰符实现的同步机制叫做互斥锁机制,它所获得的锁叫做互斥锁。每个对象都有一个monitor(锁标记),当线程拥有这个锁原创 2017-08-22 09:19:30 · 281 阅读 · 0 评论 -
并发编程6:CopyOnWriteArrayList 的写时复制
首先提个问题:线程安全的 List 集合有什么?CopyOnWriteArrayList 的特点以及使用场景?如果这个问题你答不上来,那这篇文章可能就对你有些价值。读完本文你将了解:CopyOnWriteArrayList简介CopyOnWriteArrayList源码分析Android SDK25底部实现读取操作修改操作迭代器Cop转载 2017-08-28 11:03:12 · 322 阅读 · 0 评论