One more lesson learned on “volatile varible”
Monday, July 16th, 2007Rockch left a comment on “lesson learned on synchronized method“:
rockch | July 15th, 2007 at 8:16 pm e
synchronized is so heavy for your code,you can use volatile.
http://www.ibm.com/developerworks/cn/java/j-jtp06197.html?S_TACT=105AGX52&S_CMP=techcsdn
The article is a Chinese translation, the original English version is here. After I read the article, though i though volatile variable actually can’t help me in my code (cause the init() did quite a few dirty and time costing works, so I still need synchronized method lock on other object to provide thread safe), I still learned more on volatile variables.
Frankly speaking, I never really care about “volatile variables” before, all I know before is, “volatile” tell compiler DO NOT optimized on it and it related code, and generally will be used in threads shared variables.
I copied some from original articles for my own reference.
Patterns to use volatile variables:
1. Using a volatile variable as a status flag
|
2.Using a volatile variable for safe one-time publication
public class BackgroundFloobleLoader {
public volatile Flooble theFlooble; public void initInBackground() {
// do lots of stuff
theFlooble = new Flooble(); // this is the only write to theFlooble
}
}
public class SomeOtherClass {
public void doWork() {
while (true) {
// do some stuff...
// use the Flooble, but only if it is ready
if (floobleLoader.theFlooble != null)
doSomething(floobleLoader.theFlooble);
}
}
}
|
3.Using a volatile variable for multiple publications of independent observations
public class UserManager {
public volatile String lastUser; public boolean authenticate(String user, String password) {
boolean valid = passwordIsValid(user, password);
if (valid) {
User u = new User();
activeUsers.add(u);
lastUser = user;
}
return valid;
}
}
|
@ThreadSafe
public class Person {
private volatile String firstName;
private volatile String lastName;
private volatile int age; public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public int getAge() { return age; }
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public void setAge(int age) {
this.age = age;
}
}
|
@ThreadSafe
public class CheesyCounter {
// Employs the cheap read-write lock trick
// All mutative operations MUST be done with the 'this' lock held
@GuardedBy("this") private volatile int value; public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
|
The reason this technique is called the “cheap read-write lock” is that you are using different synchronization mechanisms for reads and writes. Because the writes in this case violate the first condition for using volatile, you cannot use volatile to safely implement the counter — you must use locking
—
That article also gave some valuable links, which worth to read on…
- Java Concurrency in Practice : The how-to manual for developing concurrent programs in Java code, including constructing and composing thread-safe classes and programs, avoiding liveness hazards, managing performance, and testing concurrent applications.
- Going Atomic: Describes the atomic variable classes added in Java 5.0, which extend the concept of volatile variables to support atomic state transitions.
- An introduction to nonblocking algorithms: Describes how concurrent algorithms can be implemented without locks, using atomic variables.
- Volatiles: More about volatile variables from Wikipedia.
- The Java technology zone: Hundreds of articles about every aspect of Java programming.
Popularity: 8% [?]
About