转载请注明出处:http://blog.csdn.net/ns_code/article/details/17229601 如果线程在等待时接到通知,但线程等待的条件还不满足,此时,线程接到的就是早期通知,如果条件满足的时间很短,但很快又改变了,而变得不再满足,这时也将发生早期通知.这种现象听起来很奇怪,下面通过一个示例程序来说明问题. 很简单,两个线程等待删除List中的元素,同时另外一个线程正要向其中添加项目.代码如下: import java.util.*; public class Ea…
如果线程在等待时接到通知,但线程等待的条件还不满足,此时,线程接到的就是早期通知,如果条件满足的时间很短,但很快又改变了,而变得不再满足,这时也将发生早期通知.这种现象听起来很奇怪,下面通过一个示例程序来说明问题. ​ 很简单,两个线程等待删除List中的元素,同时另外一个线程正要向其中添加项目.代码如下: import java.util.*; public class EarlyNotify extends Object { private List list; public EarlyNo…
多条线程之间有时需要数据交互,下面介绍五种线程间数据交互的方式,他们的使用场景各有不同. 1. volatile.synchronized关键字 PS:关于volatile的详细介绍请移步至:Java并发编程的艺术(三)——volatile 1.1 如何实现通信? 这两种方式都采用了同步机制实现多条线程间的数据通信.与其说是“通信”,倒不如说是“共享变量”来的恰当.当一个共享变量被volatile修饰 或 被同步块包裹后,他们的读写操作都会直接操作共享内存,从而各个线程都能看到共享变量最新的值,…
线程间的通信 JVM在运行时会将自己管理的内存区域,划分为不同的数据区,称为运行时数据区.每个线程都有自己私有的内存空间,如下图示: Java线程按照自己虚拟机栈中的方法代码一步一步的执行下去,在这一过程中不可避免的会使用到线程共享的内存区域堆或方法区.为了防止多个线程在同一时刻访问同一个内存地址,需要互相告知自己的状态以避免资源争夺. 线程的通信方式主要分为三种方式:①共享内存②消息传递③管道流 共享内存:线程之间通过对共享内存的读-写来实现隐式通信.Java中的具体实现是:volatile共…
线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体.线程间的通信就是成为整体的必用方案之一,可以说,使线程间进行通信后,系统之间的交互性会更强大,在大大提高CPU利用率的同时还会使程序员对各线程任务在处理的过程中进行有效地把控与监督. 一.等待/通知机制 1.不使用等待/通知机制实现线程间通信 示例:线程A向数组中增加元素,线程B不断查询数组中元素个数,在元素个数等于1时发生异常并停止.虽然两个线程实现了通信,但有一个弊端就是,线程B不停地通过while语句轮询机制来检…
多线程并发执行时,不同的线程执行的内容之间可能存在一些依赖关系,比如线程一执行a()方法和c()方法,线程二执行b()方法,方法a()必须在方法b()之前执行,而方法c()必须在方法b()之后执行.这时两个线程之间就需要协作才能完成这个任务,使两个线程协作有一个简单粗暴的方法,即监控布尔变量,代码如下: boolean finishA = false; boolean finishB = false; 线程一执行下面的代码: a(); finishA = true; while(!finishB…
在现实中,需要线程之间的协作.比如说最经典的生产者-消费者模型:当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权.因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去.因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态.然后等待消费者消费了商品,然后消费者通知生产者队列有空间了.同样地,当队列空时,消费者也必须等待,等待生产者…
上篇我们讲了使用wait()和notify()使线程间实现合作,这种方式很直接也很灵活,但是使用之前需要获取对象的锁,notify()调用的次数如果小于等待线程的数量就会导致有的线程会一直等待下去.这篇我们讲多线程间接协作的方式,阻塞队列和管道通讯,间接协作的优点是使用起来更简单并且不易出错. 阻塞队列 阻塞队列提供了一种功能,即你可以在任何时刻向队列内扔一个对象,如果队列满了则当前线程阻塞:在任何时刻都可以从队列中取出一个对象,如果队列为空则当前线程阻塞.阻塞队列是线程安全的,使用它时无需加锁…
notify通知的遗漏很容易理解,即threadA还没开始wait的时候,threadB已经notify了,这样,threadB通知是没有任何响应的,当threadB退出synchronized代码块后,threadA再开始wait,便会一直阻塞等待,直到被别的线程打断. 实例见 :https://git.oschina.net/wenjieyatou/threadTest 在threadB进行通知之前,先将okToProceed置为true,这样如果threadA将通知遗漏,那么就不会进入wh…
在组合对象中如果每个组件都已经是线程安全的,是否需要再加一个额外的"线程安全层",需要视情况而定. final可以修饰未复制的属性,只要在静态代码块或者构造函数中赋值了即可. 独立的状态变量 我们还可以将线程的安全性委托给多个状态变量,只要这些变量是彼此独立的,即组合而成的类并不会在其包含的多个状态变量上增加任何不变性条件. 如果是状态变量之间存在着某些不变性条件时就没这么简单了.比如一个类中有两个属性,要满足的条件是一个属性的值要小于另一个属性的值.这是比较典型的先检查后执行的操作,…