Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。
Java语言规范中指出:为了获得最佳速度,允许线程保存共享成员变量的私有拷贝,而且只当线程进入或者离开同步代码块时才与共享成员变量的原始值对比。
这样当多个线程同时与某个对象交互时,就必须要注意到要让线程及时的得到共享成员变量的变化。
而volatile关键字就是提示VM:对于这个成员变量不能保存它的私有拷贝,而应直接与共享成员变量交互。
使用建议:在两个或者更多的线程访问的成员变量上使用volatile。当要访问的变量已在synchronized代码块中,或者为常量时,不必使用。
由于使用volatile屏蔽掉了VM中必要的代码优化,所以在效率上比较低,因此一定在必要时才使用此关键字。
java关键字Transient
转自http://horst.sun.blog.163.com/blog/static/348849612007614494492/
翻译自http://www.devx.com/tips/Tip/13726。
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想
用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。
transient是Java语言的关键字,用来表示一个域不是该对象串行化的一部分。当一个对象被串行化的时候,transient型变量的值不包括在串行化的表示中,然而非transient型的变量是被包括进去的。
首先,让我们看一些Java serialization的代码:
public class LoggingInfo implements java.io.Serializable
{
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
LoggingInfo(String user, String password)
{
uid = user;
pwd = password;
}
public String toString()
{
String password=null;
if(pwd == null)
{
password = "NOT SET";
}
else
{
password = pwd;
}
return "logon info: \n " + "user: " + uid +
"\n logging date : " + loggingDate.toString() +
"\n password: " + password;
}
}
现在我们创建一个这个类的实例,并且串行化(serialize)它 ,然后将这个串行化对象写如磁盘。
LoggingInfo logInfo = new LoggingInfo("MIKE", "MECHANICS");
System.out.println(logInfo.toString());
try
{
ObjectOutputStream o = new ObjectOutputStream(
new FileOutputStream("logInfo.out"));
o.writeObject(logInfo);
o.close();
}
catch(Exception e) {//deal with exception}
To read the object back, we can write
try
{
ObjectInputStream in =new ObjectInputStream(
new FileInputStream("logInfo.out"));
LoggingInfo logInfo = (LoggingInfo)in.readObject();
System.out.println(logInfo.toString());
}
catch(Exception e) {//deal with exception}
如果我们运行这段代码,我们会注意到从磁盘中读回(read——back (de-serializing))的对象打印password为"NOT SET"。这是当我们定义pwd域为transient时,所期望的正确结果。
现在,让我们来看一下粗心对待transient域可能引起的潜在问题。假设我们修改了类定义,提供给transient域一个默认值,
代码如下:
public class GuestLoggingInfo implements java.io.Serializable
{
private Date loggingDate = new Date();
private String uid;
private transient String pwd;
GuestLoggingInfo()
{
uid = "guest";
pwd = "guest";
}
public String toString()
{
//same as above
}
}
现在,如果我们穿行化GuestLoggingInfo的一个实例,将它写入磁盘,并且再将它从磁盘中读出,我们仍然看到读回的对象打印password 为 "NOT SET"。当从磁盘中读出某个类的实例时,实际上并不会执行这个类的构造函数,
而是载入了一个该类对象的持久化状态,并将这个状态赋值给该类的另一个对象。
分享到:
相关推荐
### Java关键字总结 Java是一种广泛使用的面向对象编程语言,它具备简单性、可移植性、高性能等特点。在Java中,关键字具有特殊的语法含义,不能用作标识符(例如变量名或方法名)。以下是对给定文件中提到的Java...
这篇文档《Java关键字详细解》将深入探讨Java中的关键字及其用途。 首先,我们来看看Java中的主要关键字。`public`、`private`、`protected`是访问修饰符,用于控制类、方法和变量的访问权限。`public`可以被任何...
### Java中的transient关键字详解 在Java编程语言中,`transient`关键字是一个非常重要的概念,主要用于对象序列化过程中对特定变量的控制。当一个类实现了`Serializable`接口时,其对象可以被序列化为一个持久化的...
### Java关键字详解 #### 概述 Java是一种广泛使用的面向对象编程语言,它拥有丰富的关键字集,用于控制程序的行为和结构。Java关键字是由Java语言预定义的标识符,具有特殊的含义,不能用作变量名、方法名或类名等...
Java关键字是编程的基础,它们是Java语言预定义的标识符,具有特殊含义并被Java编译器识别。在Java中,一共有51个关键字(包括保留字),但描述中提到的是48个,可能是因为某些关键字在特定上下文不常用或者被归类到...
### Java关键字详解 #### 前言 Java作为一种广泛使用的编程语言,在软件开发领域占据了重要的地位。Java的关键字,即保留字,是Java语言中具有特殊意义的标识符,它们预定义并保留用于语言本身的语法结构。理解这些...
下面是对Java关键字的详细解释: 1. `abstract`: 用于定义抽象类或抽象方法,表示类或方法没有具体实现,需要子类进行具体实现。 2. `boolean`: 表示逻辑值,只有两个可能的值,`true` 和 `false`。 3. `break`: ...
Java 共有 50 多个关键字,它们包括但不限于 `abstract`、`assert`、`boolean`、`break`、`byte`、`case`、`catch`、`char`、`class`、`const`(虽然未使用)、`continue`、`default`、`do`、`double`、`else`、`...
Java关键字是编程的基础,它们是Java语言预定义的、具有特殊含义的标识符,不能作为变量名、方法名或类名。以下是对50个Java关键字的详细解释: 1. **abstract**:用于声明抽象类或抽象方法,不包含具体实现。 2. ...
修饰符如`private`, `public`, `protected`定义了访问权限,`final`, `static`, `abstract`, `native`, `synchronized`, `volatile`, `strictfp`, `transient`分别用于定义不可变对象、静态成员、抽象方法、本地方法...
- 其他关键字:如void、static、final、abstract、native、transient、volatile等,各有特定用途。 2. Java关键字应用示例: - `public class HelloWorld {` 这行代码定义了一个公共类HelloWorld,可供其他类访问...
Java关键字和命名规范是Java编程语言中的基础概念,它们对于编写清晰、规范的代码至关重要。Java关键字是Java语言内置的、具有特殊用途的保留字,而命名规范则是关于如何给类、方法、变量等命名的约定。 ### Java...
下面是对Java关键字的详细总结,按照给出的部分内容进行排列: 1. `abstract`: - `abstract` 关键字用于声明抽象类或抽象方法。抽象类不能被实例化,只能作为其他类的基类。抽象方法没有具体的实现,必须在子类中...
- `public`, `private`, `protected`, `static`, `final`, `abstract`, `synchronized`, `volatile`, `transient`:这些关键字用于定义访问级别和修饰符。 - `try`, `catch`, `finally`, `throw`, `throws`:这些...
### Java关键字的用法 Java作为一种广泛使用的编程语言,拥有丰富的关键字来支持其核心功能与特性。本文将详细介绍部分重要的Java关键字及其用法。 #### 1. `abstract` `abstract`关键字用于定义抽象类或抽象方法...
10. 内存管理关键字:`transient`用于标记字段不序列化,`volatile`保证多线程环境中的可见性和有序性。 通过深入理解和熟练运用这些关键字,开发者可以编写出高效、稳定的Java程序。在学习过程中,结合实际案例来...
Java关键字是Java语言中预先定义的、具有特殊意义的单词,它们在Java程序中有着特殊的用途,比如用来声明数据类型、定义流程控制语句等。根据提供的部分内容,可以将Java的关键字分类并阐述它们的作用。 1. 访问...
这只是Java关键字的一部分,其他关键字如`enum`, `final`, `float`, `goto`, `instanceof`, `new`, `package`, `super`, `synchronized`, `this`, `throw`, `throws`, `transient`, `volatile`等也有着各自的重要...
### Java关键字详解 #### Abstract `abstract` 是Java中的一个关键字,用于定义抽象类或抽象方法。抽象类是不能被实例化的类,主要用于提供子类一个基础模板,并强制子类去实现某些特定的方法。抽象方法是没有实现...