`

java的volatile与多线程

    博客分类:
  • java
 
阅读更多
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。


Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

下面是个例子:恢复注释的任何一处都可以实现同步,就是让程序停下来
import java.util.concurrent.TimeUnit;

// Broken! - How long would you expect this program to run ?
public class StopThread {
	
	
//	private static volatile   boolean stopRequested;  // value: false
	private static   boolean stopRequested;  // value: false
	
	public static void main(String... args) throws InterruptedException {
		
		
		Thread backgroundThread = new Thread(new Runnable() {
			public synchronized  void test () {
			}
			
			@Override
			public void run() {
				int i = 0;
				while(!stopRequested){
//					test();
					i++;
				}
			}
		});
		
	
		backgroundThread.start();
		
		TimeUnit.SECONDS.sleep(1);
		stopRequested = true;
		
	}
}




当然最容易理解的是用同步的方法:
import java.util.concurrent.TimeUnit;

// Broken! - How long would you expect this program to run ?
public class StopThread {

	private static boolean stopRequested;  // value: false
	
	public static synchronized void requestStop() {
		stopRequested = true;
	}
	public static synchronized boolean stopRequested() {
		return stopRequested;
	}
	public static void main(String... args) throws InterruptedException {
		
		Thread backgroundThread = new Thread(new Runnable() {
			
			@Override
			public void run() {
				int i = 0;
				while(!stopRequested())
					i++;
			}
		});
		
		backgroundThread.start();
		
		TimeUnit.SECONDS.sleep(1);
		requestStop();
	}
}
0
2
分享到:
评论
9 楼 rainsilence 2013-02-22  
huangyunbin 写道
rainsilence 写道

lz的例子的确是Volatile的使用场景,却不直观。因为区别只有一瞬间,当stopRequested修改了后,不用  Volatile可能多执行3遍,别的线程才能发现。但是用了,可能一遍都不多执行,别的线程就能发现。用lz的例子不明显,换成淘宝的秒杀就明显了吧。


你上网查下,Volatile是肯定会被发现的,但是不用Volatile肯定不会发现,这个不存在概率问题的。而且我确实执行了多次验证的。

淘宝的秒杀是怎么样的?


用Volatile是肯定会被发现,不用Volatile不一定不会被发现,你也测出来了,其实跟jre的策略有关。
8 楼 huangyunbin 2013-02-22  
rainsilence 写道

lz的例子的确是Volatile的使用场景,却不直观。因为区别只有一瞬间,当stopRequested修改了后,不用  Volatile可能多执行3遍,别的线程才能发现。但是用了,可能一遍都不多执行,别的线程就能发现。用lz的例子不明显,换成淘宝的秒杀就明显了吧。


你上网查下,Volatile是肯定会被发现的,但是不用Volatile肯定不会发现,这个不存在概率问题的。而且我确实执行了多次验证的。

淘宝的秒杀是怎么样的?
7 楼 huangyunbin 2013-02-22  
我得到的结果是:只有jre6默认情况(client模式)是会停下来的。其他情况(如jre6的server模式 以及jre7)都是不会停的.
6 楼 rainsilence 2013-02-21  
lovexp2010 写道
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6


当然是可以停下来啦。java的变量几乎都不具有原子性,即不同的thread对于共享变量的读写,通常无法及时的反应给其他线程。为了获得更快的速度。

用Volatile可以保证变量可以在其他线程写入的瞬间读到最新值,避免脏读。

lz的例子的确是Volatile的使用场景,却不直观。因为区别只有一瞬间,当stopRequested修改了后,不用  Volatile可能多执行3遍,别的线程才能发现。但是用了,可能一遍都不多执行,别的线程就能发现。用lz的例子不明显,换成淘宝的秒杀就明显了吧。
5 楼 zjuttsw 2013-02-21  
zjuttsw 写道
lovexp2010 写道
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6

你以服务器模式运行该程序就可以达到预期结果。 java -version AppName

打错了,是 -server
4 楼 zjuttsw 2013-02-21  
lovexp2010 写道
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6

你以服务器模式运行该程序就可以达到预期结果。 java -version AppName
3 楼 xiajun_868 2013-02-21  
huangyunbin 写道
lovexp2010 写道
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6



不是吧,我的是64位的 jdk5,CPU:i3.难道和jdk有关系?我再试下

停下来时肯定会的,只是时机不同而已。没有volatile那停下来就不是准确的时机。
2 楼 huangyunbin 2013-02-21  
lovexp2010 写道
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6



不是吧,我的是64位的 jdk5,CPU:i3.难道和jdk有关系?我再试下
1 楼 lovexp2010 2013-02-21  
第一个例子,你意思不恢复注释,这个程序就停止不了?我试了,不恢复注释,运行正常,可以停下来,怎么解释?

我的环境:CPU:i5, JDK:1.6

相关推荐

    Java线程:volatile关键字

    volatile 变量可用于提供线程安全,但是只能应用于非常有限的一组用例:多个变量之间或者某个变量的当前值与修改后值之间没有约束。 正确使用 volatile 变量的条件是:对变量的写操作不依赖于当前值,以及该变量...

    java多线程Demo

    3. 多线程同步与通信: 在多线程环境下,可能会出现数据竞争问题,为了解决这个问题,Java提供了多种同步机制,如synchronized关键字、wait/notify机制、Lock锁(ReentrantLock)等。synchronized用于控制对共享...

    Java多线程知识点总结

    Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...

    java多线程的讲解和实战

    Java多线程是Java编程中的重要概念,尤其在如今的多核处理器环境下,理解并熟练掌握多线程技术对于提高程序性能和响应速度至关重要。本资料详细讲解了Java多线程的原理,并提供了丰富的实战代码,非常适合Java初学者...

    java 多线程并发实例

    - volatile:修饰变量,确保多线程环境下的可见性和有序性,但不保证原子性。在实例中,可能用于共享标志的设置与读取。 - wait()、notify()和notifyAll():这些方法存在于Object类中,用于线程间的通信。在线程A...

    基于java swing的多线程电梯调度模拟

    在本项目"基于Java Swing的多线程电梯调度模拟"中,我们主要探讨的是如何利用Java的多线程特性来实现一个复杂的系统——电梯调度。这个任务是在操作系统课程中的一个典型作业,它要求开发者模拟真实世界中的电梯运行...

    java单线程多线程clientserver

    Java中的单线程和多线程是编程中的关键概念,特别是在服务器端开发中。了解它们的原理和应用对于构建高效、可扩展的客户端-服务器应用至关重要。以下是对这些概念的详细解析。 首先,我们来谈谈单线程。在Java中,...

    Java多线程编程核心技术_完整版_java_

    Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程《Java多线程编程核心技术》将...

    JAVA多线程编程技术PDF

    首先,多线程的核心概念包括线程的创建与启动。在Java中,可以通过实现Runnable接口或继承Thread类来创建线程。创建后,调用start()方法启动线程,而非run()方法,因为start()会触发Java虚拟机(JVM)执行线程的run...

    Java多线程编程实战指南-核心篇

    本指南将通过实例分析和实践演练,让你深入理解多线程的原理与应用。 首先,我们要了解Java中的线程模型。Java通过Thread类来表示线程,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和堆。线程的创建可以...

    Java多线程练习题

    2. volatile关键字:保证了变量在多线程环境下的可见性和有序性,但不保证原子性。 3. Lock接口与ReentrantLock类:提供了比synchronized更细粒度的锁控制,具有可重入性、公平性等特点,可以配合Condition进行条件...

    java中的多线程实例详解(自己去运行看结果)

    2. `volatile`关键字:确保多线程环境下的可见性和有序性,但不保证原子性。 3. `Lock`接口及其实现类:如`ReentrantLock`,提供更灵活的锁操作,支持公平锁、非公平锁、可重入锁和定时锁等。 4. `Atomic`类:提供...

    Java多线程与线程安全实践-基于Http协议的断点续传

    在本项目“Java多线程与线程安全实践-基于Http协议的断点续传”中,我们将深入探讨如何利用Java的多线程机制实现HTTP协议下的断点续传功能,这对于大文件下载或上传的场景尤为实用。 断点续传是一种允许用户在中断...

    java多线程之赛马程序实验8多线程练习下载进度

    本实验"java多线程之赛马程序实验8多线程练习下载进度"聚焦于如何利用多线程来模拟实际场景中的下载进度显示。在这一过程中,我们将探讨Thread类的`run`和`start`方法,以及如何通过进度条来可视化表示下载过程。 ...

    java 多线程编程实战指南(核心 + 设计模式 完整版)

    - **同步机制**:包括`synchronized`关键字、`volatile`关键字、`Lock`接口及其子类,用于解决多线程环境中的数据一致性问题。 2. **并发控制** - **互斥与同步**:通过`synchronized`关键字实现临界区的互斥访问...

    java多线程进度条实例

    在Java编程中,多线程是一项关键特性,它允许程序同时执行多个任务,极大地提高了效率。本实例将探讨如何利用Java实现一个具有进度条显示功能的多线程应用。进度条通常用于可视化地表示某个任务的完成程度,这对于长...

    JAVA-JavaThreadProgramming-Sams.zip_JAVA 设计_java 多线程_java 线程_多线程

    Java提供了多种同步机制来解决多线程环境下的数据安全问题,如synchronized关键字、 volatile变量、Lock接口(如ReentrantLock)以及Semaphore信号量等。synchronized提供了内置锁,可以保证同一时刻只有一个线程...

    Java多线程详解及示例

    3. 多线程中的死锁与活锁 在多线程环境下,死锁是指两个或多个线程相互等待对方释放资源,导致它们都无法继续执行。活锁则是指线程不断重试获取资源,但由于其他线程持有资源不释放,导致线程陷入无限循环的状态。...

    java 多线程的小游戏 Java 课程设计 Java毕业设计 多线程的小游戏 经典

    Java多线程小游戏是学习Java并发编程的一个经典实践案例,它可以帮助开发者深入理解线程的创建、同步、通信以及管理。在这个课程设计或毕业设计项目中,学生通常会被要求实现一个能够展示多线程特性的游戏,比如经典...

    java多线程设计

    3. 线程同步:Java提供了多种同步机制,如synchronized关键字、volatile变量、Lock接口(ReentrantLock等)、Semaphore信号量、CyclicBarrier屏障等,用于解决多线程环境下资源竞争和数据一致性问题。 二、不可变...

Global site tag (gtag.js) - Google Analytics