当前位置:首页 > 开发 > 编程语言 > 多线程 > 正文

Java多线程与并发学习笔记

发表于: 2013-12-31   作者:darrenzhu   来源:转载   浏览次数:
摘要: Volatile Volatile的英文解释:adj.易变的,不稳定的. 对于Volatile类型的变量来说,上一次写入操作的结果对下一次读取操作是肯定可见的。在写入volatile变量值之后,CPU缓存中的内容会被写回主存,在读取volatile变量时,CPU缓存中的对应内容被设置为失效状态,重新从主存中进行读取。将变量声明为volatile相当于为单个变量的读取和写入添加了同步操作。但是v
Volatile
Volatile的英文解释:adj.易变的,不稳定的.
对于Volatile类型的变量来说,上一次写入操作的结果对下一次读取操作是肯定可见的。在写入volatile变量值之后,CPU缓存中的内容会被写回主存,在读取volatile变量时,CPU缓存中的对应内容被设置为失效状态,重新从主存中进行读取。将变量声明为volatile相当于为单个变量的读取和写入添加了同步操作。但是volatile在使用时不需要利用锁机制,因此性能要由于synchronized关键词。


public class Worker {
	private volatile boolean done;
	public void setDone(boolean done) {
		this.done = done;
	}
	public void work() {
		while (!done) {
			//do something
		}
	}
}


对于上面的例子,当线程A调用lWorker类的对象的work方法,开始执行具体的任务。在适当的时候线程B会调用同一Work类的对象的setDone方法来声明终止任务的执行。把done变量声明为volatile是很重要的。只有这样才能保证线程B对done变量所做的修改对线程A的后续操作是可见的。否则,线程A可能由于无法看到done变量值的变化而一直运行下去。

但是虽然volatile关键词使用简单,但是由于在实现时没有锁机制的存在,volatile关键词的适用场景是受限的。比如对于下面的例子:


public class IdGenerator {
	private int value = 0;
	public int getNext() {
		return value++;
	}
}


注释: 虽然getNext方法只有一行代码,但是这一行代码对应的字节码指令却是7条。
如果只是把value声明为volatile是不够的,仍然会出现问题。这是因为写入的value的正确值依赖于value的当前值,而当前值有可能是不正确的。假设线程A获取了value的当前值1却发生了线程切换,如果线程B把value改成2后,线程A才获得了执行,这个时候A所持有的当前值1就已经不是正确的了。当要写入的新值与当前值没有关系时,使用volatile就足够了。

原子操作:
在Java中,对于非long型和double型的域的读取和写入操作是原子操作。对象引用的读取和写入操作也是原子操作。比如读取一个int型的域时,该域对应的内存地址中的32位的内容会被完整读取,在读取过程中不会被其他线程所打断。在写入操作时也不会被打断。在写入非volatile的long型和double型的域的值时,分成两次操作来完成。一个long型或double型的域的长度是64位,每次写入32位。在一个线程写入了long型或double型的域的前32位之后,在写入后32位之前,另外一个线程有可能访问这个域的值,从而读取只完成部分写入操作的错误值。因此在多线程程序中使用long型和double型的共享变量时,需要把变量声明为volatile,以保证读取和写入的完整性。
另外注意这里说的类型时基本类型,并不是封装类型,封装类型事实上是object.


可见性:

Java多线程与并发学习笔记

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
进程:正在执行中的程序,其实是应用程序在内存中运行的那片空间。(只负责空间分配) 线程:进程中
概念部分: 1.并发和并行的区别:   并发 (Concurrency):一个处理器“同时”处理多个任务   并
Java SE5的java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编
关键字: 原子操作:原子为不可再分操作。 Violation :可见关键字。 Synchronized:内部隐示锁 Ree
为啥需要并发: 个人英雄主义,单人独写xx软件的传奇,回味孤独英雄的寂寞。 系统运行也不是单个计
Java SE5的java.util.concurrent包中的执行器(Executor)将为你管理Thread对象,从而简化了并发编
关键字: 原子操作:原子为不可再分操作。 Violation :可见关键字。 Synchronized:内部隐示锁 Ree
资源下载地址:http://download.csdn.net/detail/cloudyxuq/3763101 七.Callable和Future接口 C#可
资源下载地址:http://download.csdn.net/detail/cloudyxuq/3763101 四.多线程的同步 以一个取钱列
资源下载地址:http://download.csdn.net/detail/cloudyxuq/3763101 一.线程的创建和启动 java使用
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号