具体作用就不多讲了,大概就是保证可见性和防止重排序。 其实很早前就知道有这个关键字,试过很多次,总觉得加了和没加效果一样。
这次终于在阅读《java并发程序实践》(顺便义务广告一下,好书)的时候有了灵感,写了一段很普通的代码:
public class NoVisibility {
private boolean ready=false;
int num;
private class ReaderThread extends Thread {
public void run() {
int count = 0;
while (!ready)
{
count++;
}
System.out.println(num);
}
}
public static void main(String[] args) throws InterruptedException {
NoVisibility x = new NoVisibility();
x.new ReaderThread().start();
x.num = 43;
x.ready = true;
System.out.println("main Thread end");
}
}
再写一段python来不停地调用它(因为不一定总能出现),不久后就会发现不返回了,ready值的更新一直对ReaderThread线程不可见。如果ready加个volatile就不会有问题了,可以一直运行。
import os
i=0
while True:
os.system("java -server NoVisibility")#or os.popen
i+=1
print "run count"+str(i)
感受:
1.java运行时加参数-server用server版的虚拟机出问题几率很高,据说是server才经过大量优化。
2.while (!ready)的循环内如果有System.out操作时,也几乎不出问题,提高了可见性?(这个是我的猜测)
=====2011.3.19=======《java并发编程实践》其实给出个更好的例子===============
由于asleep在循环中没改变,所以在server版的jvm中会被优化,提出循环判断,结果搞成个死循环。这个是必现得
java -server -cp . visibility
public class visibility {
boolean asleep = false;
public void run1()
{
int i=0;
while (!asleep)
i++;
System.out.println(i);
System.out.println("end");
}
public static void main(String[] args) {
final visibility a = new visibility();
new Thread(){
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
a.asleep = true;
};
}.start();
a.run1();
}
}
分享到:
相关推荐
- **Applet**: 小应用程序,早期Java中的一种应用形式,可以在网页中嵌入并运行。 - **Public**: 访问修饰符,表示公开的,即可以被任何其他类访问。 - **Static**: 静态的,表示类的成员变量或方法是属于类本身的,...
Java_Volatile Java_jmap_histo_pid Java_jmeter_server_polling_pressure_test Java_jstack Linux_Copy_On_Write Linux_Hydra Linux_Pip Linux_Redis_Make Linux_Shell_GetAndPost Linux_Vim Linux_XShell_File_...
D) 在show()方法中可以为day进行赋值,因为Test2继承了Test,则在Test2中也继承了父类的day变量。 题目13: 下面哪个关键字,使类不能在被其他的类继承?c(选择1项) A) static B) finally C) final D) instance ...
- **并发变量**:使用`volatile`关键字声明,用于并发环境中,确保变量的可见性。 3. **成员方法**: - **可见性**:与成员变量相同。 - **静态方法**:通过`static`关键字声明,可以直接通过类名调用。 - **不...
在Java编程中,设计模式是一种常见的编码规范,用于解决软件设计中反复出现的问题,提高代码的可读性和可维护性。本文将详细讲解两种常用的设计模式:单例模式和工厂模式,并通过实例来阐述它们的应用。 **单例模式...
在Java、C#、Python等面向对象的语言中,都可以实现单例模式。下面将详细介绍单例模式的实现方式以及其优缺点。 ### 单例模式的实现方式: 1. **饿汉式(静态常量)**: 在类加载时就完成了初始化,所以没有安全...
首先,我们来了解一下什么是单例模式。单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在Android应用中,特别是在涉及到全局状态或者需要在整个应用生命周期内共享的对象时,单例模式...
- 不能是 Java 中的关键字。 **2. 运算符(前置后置的区别)** - 前置运算符(如 `++a` 或 `--a`)先进行自增或自减操作,然后再返回新的值。 - 后置运算符(如 `a++` 或 `a--`)先返回当前值,然后再进行自增或...
private static volatile Toasty instance; private Toasty() {} public static synchronized Toasty getInstance() { if (instance == null) { instance = new Toasty(); } return instance; } } ``` **...
apks are nothing more than a zip file containing resources and compiled java. If you were to simply unzip an apk like so, you would be left with files such as classes.dex and resources.arsc. $ unzip...
在Android开发中,Xutils3是一个非常流行的开源框架,它为开发者提供了丰富的功能,包括数据库操作、图片加载、网络请求等。本篇文章将详细讲解如何对Android Xutils3的网络请求进行封装,并提供实例代码供参考。 ...