3.类一级的静态变量能否锁定
发表于:2007-07-01来源:作者:点击数:
标签:
Lock smith Can you lock class-level static variables? Summary ---- Can I lock class-level (static) variables? A static member attribute can be modified by more than one calling program at a time; can I somehow make sure it@#s locked? I cou
Lock smith
Can you lock class-level static variables?
Summary
-->-->
Can I lock class-level (static) variables? A static member attribute can be modified by more than one calling program at a time; can I somehow make sure it@#s locked? I could think of using something like:
synchronized(this.class)
inside the method that modifies the variable. Also, I think I will need to make the static variable private. But does it make sense to make it private? Then I would give one public static function that allows modification to this variable. Also, in this method I should use:
synchronized(this.class) {
// modify the static attribute here.
} // End of synchronized block.
Will this ensure that no two modifying threads can modify it at the same time?
You ask an interesting question. The quick answer is yes, you can lock a class variable and I@#ll show you how (though you are close)!
First, any member variable that you wish to make thread safe
must be declared private. Consider the following code:
public class MyPoint
{
public int x;
public int y;
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public synchronized setX(int x)
{
this.x = x;
}
public synchronized getY(int y)
{
this.y = y;
}
}
If this were an ideal world, everyone would set x and y by calling setX() and setY(), respectively. However, we all know that someone will come along and set x or y directly, since we defined the members as public. And since we defined x and y as public, it is reasonable for someone to come along and a
clearcase/" target="_blank" >ccess the variables directly. If we didn@#t want someone to access the members directly, we shouldn@#t have declared them as public in the first place! The only way to guarantee that threads will access x and y safely is to declare them as private and provide synchronized access.
Nothing changes when you declare a member static. If you don@#t want some thread to come along and bypass your careful synchronization, don@#t declare the member public or protected.
Now, the question remains: how do we lock the member? Sometimes I think that part of the confusion around synchronization stems from a misunderstanding of what actually happens when you call synchronized(some_object). Calling synchronized on some_object does not prevent access to some_object. Instead, you must think of synchronized as a request to open a lock around some piece of code for your thread. some_object is the lock that you wish to have access to. Only one thread may hold a specific lock at any one time.
Making a static member thread safe is fairly simple once you understand what really happens when you call synchronized. Here is a template to follow (there are many more ways to do it, though):
class Safe {
... other class definitions ...
private static <type> var;
public final synchronized static setVar(<type> val)
{
var = val;
}
}
As a second option, you can also synchronize within the method. Which approach you take will depend upon your code. However, in this example, either way is equivalent, since a synchronized static method grabs the lock on the class. You would use the second option if you were doing a lot of processing inside of the method. That way you only synchronize when you have to -- thus improving performance.
You would need to use synchronization within the method if you didn@#t want to declare setVar() static. A nonstatic method declared as synchronized locks on the instance, not the class. So, if you had more than one instance, the member would no longer be thread safe.
原文转自:http://www.ltesting.net