Java中volatile和transient关键字的区别
就像其他编程语言一样,Java也有一组保留的关键词,它们具有特殊的含义。在这篇文章中,我们将看到关键字 volatile
和 transient
之间的区别。
在讨论这些区别之前,让我们首先了解它们各自的实际含义。
volatile关键字
volatile
关键字用于标记JVM和线程从主内存读取其值,而不是利用线程栈中的缓存值。它被用于java的并发编程中。
class YiibaiDemo extends Thread {
// using volatile
volatile boolean working = true;
// if non-volatile it will sleep in main and runtime error will coocur
public void run()
{
long count = 0;
while (working) {
count++;
}
System.out.println("Thread terminated." + count);
}
// Driver code
public static void main(String[] args)
throws InterruptedException
{
YiibaiDemo test = new YiibaiDemo();
test.start();
Thread.sleep(100);
System.out.println("After Sleeping in Main");
test.working = false;
test.join();
System.out.println("Working set to " + test.working);
}
}
transient 关键字
transient关键字与实例变量一起使用,以在序列化过程中消除它。在序列化过程中,暂存字段或变量的值不被保存。
import java.io.*;
class Test implements Serializable {
// Making Accesskey transient for security
transient String accessKey;
// Making age transient as age can be
// calculated from Date of Birth
// and current date.
transient int age;
// serialize other fields
String name, address;
public Test(String accessKey, int age,
String name, String address)
{
this.accessKey = accessKey;
this.age = age;
this.name = name;
this.address = address;
}
}
public class YiibaiDemo {
public static void main(String[] args)
throws Exception
{
ObjectInputStream in
= new ObjectInputStream(
(new FileInputStream(
"login_details.txt")));
Test obj = (Test)in.readObject();
/* Transient variable will be shown
null due to security reasons.*/
System.out.println("Accesskey: " + obj.accessKey);
System.out.println("Age: " + obj.age);
System.out.println("Name: " + obj.name);
System.out.println("Address: " + obj.address);
}
}
下表描述了这些区别。
transient | volatile |
---|---|
transient标记的变量可以防止它被序列化。 | volatile 标记的变量在多线程的java程序中遵循可见性的先发生关系,这减少了内存一致性错误的风险。 |
transient提供了控制和灵活性,可以从序列化过程中排除一些对象方法。 | volatile 可以防止JVM进行重新排序,这可能会影响到同步性。 |
在反序列化过程中,它们被初始化为一个默认值。 | volatile 不是以默认值初始化的。 |
transient不能与静态关键字一起使用,因为静态变量不属于单个实例。在序列化过程中,只关注对象的当前状态。 | volatile 可以与 static 关键字一起使用。 |
transient不能与final关键字一起使用。虽然JVM没有抱怨,但在反序列化过程中,人们将面临重新初始化变量的问题。 | volatile 可以与 final 关键字一起使用。 |