Happens-Before规则程序顺序规则。如果程序中操作A在操作B之前,那么在线程中A操作将在B操作之前执行。监视器锁规则。在监视器锁上的解锁操作必须在同一个监视器锁上的加锁操作之前执行。volatile变量规则。对volatile变量的写入操作必须在对该变量的读操作之前执行。线程启动规则。在线程上对Thread.start的调用必须在该线程中执行任何操作之前执行。线程结束规则。线程中的任何操作都必须在其他线程检测到该线程已经结束之前执行...
Java并发编程之验证volatile不能保证原子性通过系列文章的学习,凯哥已经介绍了volatile的三大特性。1:保证可见性 2:不保证原子性 3:保证顺序。那么怎么来验证可见性呢?本文凯哥(凯哥Java:kaigejava)将通过代码演示来证明为什么说volatile不能够保证共享变量的原子性操作。我们来举个现实生活中的例子:中午去食堂打饭,假设你非常非常的饥饿,需要一荤两素再加一份米饭。如果食堂打饭的阿姨再给你打一个菜的时候,被其他人打断...
「 盛年不重来,一日难再晨,及时当勉励,岁月不待人。」 陶渊明我们已经知道同步代码块和同步方法可以保证以原子的方式执行,其实,同步还有另外一个重要概念:内存可见性。换句话说,我们不仅希望防止某个线程正在使用对象状态而另一个线程同时在修改状态,而且希望确保当一个线程修改了对象的状态后,其他线程能够看到修改后的状态。可见性一个线程对共享变量值的修改,能够及时的被其他线程看到。可见性微妙的,这是因为可能发生...
Java并发编程之CAS二源码追根溯源在上一篇文章中,我们知道了什么是CAS以及CAS的执行流程,在本篇文章中,我们将跟着源码一步一步的查看CAS最底层实现原理。本篇是《凯哥(凯哥Java:kagejava)并发编程学习》系列之《CAS系列》教程的第二篇:从源码追根溯源查看CAS最底层是怎么实现的。本文主要内容:CAS追根溯源,彻底找到CAS的根在哪里。一:查看AtomicInteger.compareAndSet源码通过上一篇文章学习,我们知道了AtomicInteger.comp...
ReentrantLock是一个较为常用的锁对象。在上次分析的uil开源项目中也多次被用到,下面谈谈其概念和基本使用。概念一个可重入的互斥锁定 Lock,它具有与使用 synchronized 相同的一些基本行为和语义,但功能更强大。名词解释:互斥表示同一时刻,多个线程中,只能有一个线程能获得该锁。但是多个线程都可以调用lock方法,只有一个会成功,其他的线程会被阻塞,直到该锁被释放可重入模仿synchronized 的语义;如果线程进入由线程已经...
Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问。本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.locks包下提供了另外一种方式来实现同步访问,那就是Lock。 也许有朋友会问,既然都可以通过synchronized来实现同步访问了,那么为什么还需要提供Lock?这个问题将在下面进行阐述。本文先从synchronized的缺陷讲起,然后再讲述java.util.concurrent.locks包下常用...
JDK5中添加了新的concurrent包,相对同步容器而言,并发容器通过一些机制改进了并发性能。因为同步容器将所有对容器状态的访问都串行化了,这样保证了线程的安全性,所以这种方法的代价就是严重降低了并发性,当多个线程竞争容器时,吞吐量严重降低。因此Java5.0开始针对多线程并发访问设计,提供了并发性能较好的并发容器,引入了java.util.concurrent包。与Vector和Hashtable、Collections.synchronizedXxx()同步容器等相比,uti...
在学习锁优化时,对象头(Mark Word) 是必不可缺的一环,因为synchronized 用的锁是存在对象头里的。32位的虚拟机上对象头占64位(8字节),64位的虚拟机上对象头占128位(16字节)[^objectHead];而不同的类型,对象头的布局不太一样:数组类型:Mark Word、Class Metadata Address、Array Length普通类型:Mark Word、Class Metadata AddressMark Word 表示对象的HashCode 或 锁信息Class Metadata Address 表示对象的数据类型在方...
日志服务需要提供的功能有:可以从外部安全地开启和关闭日志服务;可以供多个线程安全地记录日志消息;在日志服务关闭后,可以把剩余未记录的消息写入日志文件; publicclass LogService
{privatefinal BlockingQueue<String> msgQueue; //阻塞的消息队列保存日志消息privatefinal PrintWrite writer; //写消息到日志文件privatefinal LoggerThread logThread; //写日志的线程privat...
首先通过 MyThread 类实现 Runnable 接口,然后重写 run() 方法,之后只需要把这个实现了 run() 方法的 MyThread 实例传到 Thread 类中就可以实现多线程。如何运行Runnable线程:
MyThread a = new MyThread();new Thread(a).start();
[](
)继承 Thread 类------------------------------------------------------------------------------
class MyThread extends Thread { // 这就是一个多线程的操作类private String name ; ...
第7章:JAVA中的13个原子操作类第8章:JAVA中的并发工具类第9章:JAVA中的线程池原文:http://www.cnblogs.com/YDDMAX/p/5645191.html
任务的定义大多数并发程序都是围绕任务进行管理的.任务就是抽象和离散的工作单元. 任务的执行策略 1.顺序的执行任务这种策略的特点是一般只有按顺序处理到来的任务.一次只能处理一个任务,后来其它任务都要等待处理.响应性很糟糕,吞吐量低.系统资源利用率低.2.显示的为任务创建线程为每个任务创建对应一个线程,响应快,系统资源利用路高.缺点是资源消耗量大,如果有大量任务要执行的话,系统迟早会因为无限制创建过多的线程而造成内存...
林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka 摘要: 本文主要讲了Java当中的线程池的使用方法、注意事项及其实现源码实现原理,并辅以实例加以说明,对加深Java线程池的理解有很大的帮助。 首先,讲讲什么是线程池?照笔者的简单理解,其实就是一组线程实时处理休眠状态,等待唤醒执行。那么为什么要有线程池这个东西呢?可以从以下几个方面来考虑:其一、减少在创建和销毁线程上所花的时...
设计线程安全类套路一: 实例限制假如现在有一个非线程安全类, 让它可以被多线程安全访问, 可以做一层封装. 多线程 只通过 封装类进行访问.注意事项, 一定要加对锁!套路二: 返回深拷贝若一个对象是可变对象, 假如不是太频繁地作为参数或者返回值传递, 可以通过每次在传递时, 构建深拷贝来保证线程安全.这样做的缺点是:要求对象以及所引用的对象(包括下层引用), 都有深拷贝的方法若调用太频繁, 会产生性能问题返回的对象是一份拷贝, ...
LinkedBlockingQueue的实现是使用独占锁实现的阻塞队列。首先看一下LinkedBlockingQueue 的类图结构,如下图所示: 如类图所示:LinkedBlockingQueue是使用单向链表实现,有两个Node分别来存放首尾节点,并且里面有个初始值为0 的原子变量count,它用来记录队列元素个数。另外里面有两个ReentrantLock的实例,分别用来控制元素入队和出队的原子性,其中takeLock用来控制同时只有一个线程可以从队列获取元素,其他线程必须等待,p...