您的位置:首页 > 编程语言 > Java开发

java关键字之transient和volatile解析

2014-08-30 11:08 417 查看

transient关键字

Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。

volatile关键字

volatile关键字是一种轻量级的同步方法,什么叫轻量级呢?锁提供了两种主要特性:互斥(mutual exclusion)和可见性(visibility)。互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的
—— 如果没有同步机制提供的这种可见性保证,线程看到的共享变量可能是修改前的值或不一致的值,这将引发许多严重问题。这里volatile可以理解为一种锁可见性。什么意思?直接看代码!

package test;
public class Main {
public volatile static int count = 0;
//AtomicInteger 加锁的操作
public static Object object = new Object();
public static void inc() {
//这里延迟1毫秒,使得结果明显
try {
Thread.sleep(1);
} catch (InterruptedException e) {
}
count++;
}

public static void main(String[] args) throws InterruptedException {
//同时启动1000个线程,去进行i++计算,看看实际结果
for (int i = 0; i < 1000; i++) {
new Thread(new Runnable() {
public void run() {
Main.inc();
}
}).start();
}
Thread.sleep(1000);
//这里每次运行的值都有可能不同,可能为1000
System.out.println("运行结果:Counter.count=" + Main.count);
}
}
结果是:运行结果:Counter.count=982

所以volatile并没有提供绝对的互斥访问,它的原理可以理解为如下:



这里以两个线程为例子:1线程读取i的值0等++完后变为1然后存回去I里面,但是很可能2线程在存回去之前读取了这个值,所以它获取的I值也为0,这样就不能同步,但是每当i值变换的时候都会去通知别的线程i值变了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: