Today, I saw the interesting question: what is the difference between locking and non-static methods on static methods, so that some understanding of the lock mechanism is introduced again.
First look at the method:
This is a very simple class that shares static variable num, and then a static and non-static method, all with a lock
We assume that there are two threads that operate both methods simultaneously, so can data be mutually exclusive?
Java code
- Public class Walk {
- public static int num = 100;
- public static Walk Walk = new Walk ();
- //Static
- public synchronized static int run () {
- int i = 0;
- While (I < ) {
- try {
- Num--;
- i++;
- System.out.println (Thread.CurrentThread (). GetName () +":" +num);
- Thread.Sleep (1000);
- } catch (Interruptedexception e) {
- E.printstacktrace ();
- }
- }
- return num;
- }
- //non-static
- public synchronized int Walk () {
- int i = 0;
- While (I < ) {
- try {
- Num--;
- i++;
- System.out.println (Thread.CurrentThread (). GetName () +":" +num);
- Thread.Sleep (1000);
- } catch (Interruptedexception e) {
- E.printstacktrace ();
- }
- }
- return num;
- }
- }
- First set up two test classes, here we loop 10 times by default
- Public class T3 implements Runnable {
- @Override
- public Void Run () {
- Walk Walk = new Walk ();
- //walk Walk = Walk.walk;
- Walk.walk ();
- }
- }
- Public class T1 implements runnable{
- @Override
- public Void Run () {
- Walk Walk = new Walk ();
- //walk Walk = Walk.walk;
- //Here I still use the new
- Walk.run ();
- }
- }
Java code
- Test method
- Public class Test {
- public static void Main (string[] args) {
- Thread T1 = new Thread (new T1 ());
- thread t3 = new Thread (new T3 ());
- Executorservice es = Executors.newcachedthreadpool ();
- Es.execute (t1);
- Es.execute (T3);
- Es.shutdown ();
- }
- }
Test data I'm not completely listed.
Pool-1-thread-1:98
Pool-1-thread-2:98
pool-1-thread-2:97
pool-1-thread-1:96
.....
You can see that two threads are not mutually exclusive, which is why?
OK, we will remove the static keyword, the code I will not post, directly see the results.
Pool-1-thread-1:98
Pool-1-thread-2:98
pool-1-thread-2:96
...
The result is that there is no mutex, so we have to let a thread execute 10 times by default, assuming that this is the ticket system which is not allowed. Why this happens, the method is added to the lock.
First, the understanding of the lock is introduced, and then explained from the back forward.
JAVA's lock mechanism description: Each object has a lock and is unique. Suppose an object space is allocated, there are several methods, the equivalent of space inside a number of small rooms, if we lock all the small rooms, because this object has only one key, so at the same time only one person can open a small room, and then use it back, and then by the JVM to assign the next person to get the key.
In the second experiment, we locked the method, but didn't get the result we wanted because of the room and the key. Because each of our threads is a new object when invoking the method, there are two spaces, two keys, and only one static variable, which is equivalent to having two keys, opening a shared value from a different room, and therefore making an error.
What if we use static variable walk? This code release, that is, we use an object to manipulate the variable, then the result:
Use Walk.walk.walk (); and Walk.run ();
Result: There is still no mutex
pool-1-thread-1:99
Pool-1-thread-2:98
pool-1-thread-1:97
...
If we remove the static method keyword: We can see the mutex.
pool-1-thread-1:99
Pool-1-thread-1:98
pool-1-thread-1:96
The results are still repeated, so we can draw a lock on the static method and lock it on the normal method, they are not using the same place, not the same key. So that their object locks are different and objects are different.
Here again, a concept: object locks and Class locks
Object Lock: When the JVM creates the object, the default is to give each object a unique object lock, a key
Class Locks: Each class is an object, and each object has an object lock.
Hehe, the concept of confusion, in fact, are locked, take two nouns, the following easy to distinguish, the effect is the same, if we achieve this.
Java code
- Static, this simply turns the method into a class lock.
- public static int run () {
- synchronized (Walk. Class) {
- int i = 0;
- While (I < ) {
- try {
- Num--;
- i++;
- System.out.println (Thread.CurrentThread (). GetName () +":" +num);
- Thread.Sleep (1000);
- } catch (Interruptedexception e) {
- E.printstacktrace ();
- }
- }
- return num;
- }
- }
Results:
Pool-1-thread-1:98
Pool-1-thread-2:98
pool-1-thread-2:97
pool-1-thread-1:97
...
The result is not mutually exclusive, indicating that the lock on the static method, and the instance method lock, object lock is actually not the same. If we change to:
Synchronized (walk) {
//.... Slightly
}
Results:
pool-1-thread-2:99
Pool-1-thread-2:98
pool-1-thread-2:97
This is mutually exclusive, because T1 is called by the static variable walk, the default is to use the Walk object this lock, and static method force let him also use walk this lock, there is a mutual exclusion phenomenon, because the key only one.
What if all two of our methods are static methods?
..
Summary:
1. Object lock key Only one can be mutually exclusive, in order to guarantee the uniqueness of shared variables
2. In the static method of the lock, and the instance method on the lock, the default is not the same, if the synchronization needs to make two locks.
3. The lock on a method of the same class comes from the object that called the method, and if the object calling the method is the same, then the lock must be the same, otherwise it will be different. For example, new A (). x () and new A (). x (), the object is different, the lock is different, if a's simple interest, it can be mutually exclusive.
4. Static method lock, can be locked with all other static methods of mutual exclusion
5. Static method lock, and Xx.class lock effect, directly belongs to the class
Static method lock, and non-static method lock difference