Private int I=0;
Public static void main (String [] args) {
The Object o=new Object ();
The lock=new Lock02 Lock02 ();
New Thread (() - & gt; {
for (int i=0; I & lt; 100; I++) {
Synchronized (o) {
The lock. I++;
String name=Thread. CurrentThread (). The getName ();
System. The out. Println (lock i. + ": :" + name);
}
}
}). The start ();
New Thread (() - & gt; {
for (int i=0; I & lt; 100; I++) {
Synchronized (o) {
The lock. I++;
String name=Thread. CurrentThread (). The getName ();
System. The out. Println (lock i. + ": :" + name);
}
}
}). The start ();
}
}
This is a test of object lock why print result unexpectedly is interlaced
1: : Thread - 0
2: : Thread - 0
3: : Thread 1
4: : Thread 1
5: : Thread 1
6: : Thread 1
7: : Thread 1
Not obtain an object lock method does not perform the lock don't release here seems to be lock release??????? Why is this so
CodePudding user response:
You put the synchronized (o) on the front for try to know,Left the synchronized (o) {} braces, the lock is released automatically, you are in the for lock, so every time into the circulation two threads need to grab the lock, grab the lock will have the opportunity to perform a cycle; And if a synchronized (o) in a for loop, can guarantee to lock after finish for loop execution to release the lock, this is not the same,
CodePudding user response:
Synchronized has two kinds of usage, is A kind of synchronous method (including static and non-static methods), one kind is synchronized code block. The JVM in the implementation will be increased in the constant pool method_info ACC_SYNCHRONIZED symbol to mark method is synchronized methods, use the monitorenter and monitorexit instructions to realize the synchronized code block. When it encounters the ACC_SYNCHRONIZED or monitorenter, that is to say, when A Thread synchronization methods or A synchronized code block, Thread A possession will obtain the lock object Monitor, if you don't succeed, is in Thread. State. The BLOCKED State, if successful, will perform synchronization method or synchronized code block code, and execution of the code or some abnormal release Monitor possession. Simplified is acquiring A lock - & gt; Execute code - & gt; Releases the lock . Back to your question, thread, possession of 0 to lock the object's Monitor first began to execute the code, while the thread one possession without access to lock the object's Monitor, is in the blocking state, possession waiting for access to lock the object's Monitor thread 0 execution after the code in a synchronized block, release the lock object Monitor possession, thread and thread 0 1 began to take possession Monitor lock object, and then is to lock the object's Monitor in possession of the thread continue synchronized code block code, and repeat the process, from your post, is thread 0 robbed twice before, and is followed by thread 1 grabbed.
Public class Lock02 {
Public static synchronized void once function1 () {
}
Public static void function2 () {
}
Public void function3 () {
Synchronized (Lock02. Class) {
}
}
}
Here is to use javap -c -v decompiled Lock02 out part of my information, because some information is a little long, I have deleted
Public class Lock02
{
Public static synchronized void once function1 ();
Descriptor: (a) V
Flags: ACC_PUBLIC ACC_STATIC, ACC_SYNCHRONIZED//note that the ACC_SYNCHRONIZED here
Code:
Stack=0, locals=0, args_size=0
0: return
LineNumberTable:
Line 13:0
Public synchronized void function2 ();
Descriptor: (a) V
Flags: ACC_PUBLIC, ACC_SYNCHRONIZED//note that the ACC_SYNCHRONIZED here
Code:
Stack=0, locals=1, args_size=1
0: return
LineNumberTable:
Line 16:0
Public void function3 ();
Descriptor: (a) V
Flags: ACC_PUBLIC
Code:
Stack=2, locals=3, args_size=1
0: LDC # 2//class Lock02
2: the dup
3: astore_1
4: monitorenter//take care of monitorenter here
5: aload_1
6: monitorexit//take care of monitorexit here
7: goto 15
10: astore_2
11: aload_1
12: monitorexit
13: aload_2
14: athrow
15: return
}
Original text:
"instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.
Synchronization of sequences of instructions is typically 2 to encode the synchronized block of the Java programming language. The Java Virtual Machine supplies the monitorenter and monitorexit instructions to support to language constructs. The Proper implementation of synchronized blocks the requires currency from a compiler targeting the Java Virtual Machine (§ 3.14).
"
The original
"
Monitorenter
Operation
Enter the monitor for object
The Format
Monitorenter
Forms
Monitorenter=194 (0 xc2)
Operand Stack
. From objectref,
.
The Description
The objectref must be of a type reference.
Each object is associated with a monitor. The monitor is a locked The if and only if it has an owner. The thread that executes monitorenter attempts to gain ownership of The monitor associated with objectref, as follows:
If the entry the count of the monitor associated with objectref is zero, the thread enters the monitor and sets its entry count to one. The thread is then the owner of the monitor.
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull