Today, I raised a question about ++ operations and thread security on iteye. One of my friends answered this question and said that I had a deeper understanding of Java thread locks. Here is a summary for your reference. Let's take a look at several pieces of code! Code 1: [java] public class TestMultiThread2 implements Runnable {private static Object o = new Object (); private static Integer si = 0; private static AtomicInteger flag = new AtomicInteger (); @ Override public void run () {for (int k = 0; k <2000000; k ++) {synchronized (si) {si ++ ;}} flag. incrementAndGet ();} public static void main (String [] args) throws InterruptedException {TestMultiThread2 t1 = new Tes TMultiThread2 (); TestMultiThread2 t2 = new TestMultiThread2 (); ExecutorService exec1 = Executors. newCachedThreadPool (); ExecutorService exec2 = Executors. newCachedThreadPool (); exec1.execute (t1); exec2.execute (t2); while (true) {if (flag. intValue () = 2) {System. out. println ("si >>>>" + si); break;} Thread. sleep (50) ;}}} for ease of reading, repeated code is not inserted. From Code 2 to code 4, only the code in the run () method is inserted. Code 2 is the same in other places: [java] public void run () {(Int k = 0; k <2000000; k ++) {synchronized (o) {si ++ ;}} flag. incrementAndGet ();} code 3: [java] public void run () {for (int k = 0; k <2000000; k ++) {synchronized (o) {si ++; o = new Object () ;}} flag. incrementAndGet ();} code 4: [java] public void run () {for (int k = 0; k <2000000; k ++) {synchronized (o) {si ++; Object temp = o; o = new Object (); o = temp ;}} flag. incrementAndGet ();} with these four pieces of code, I can probably understand the problem. Let's talk about the output here. Code 1: <4000000 Code 2: = 4000000 code 3: <4000000 code 4: <4000000 (PS: The result is very close to 4000000) Here describes the problems I encountered during the test, code 4 has never ran out of the desired results, mainly because I set too few cycles at the beginning, in fact, if you want this phenomenon to be more obvious here, you can add several new objects in the middle as follows: Code 5. This phenomenon is more obvious. code 5: [java] public void run () {for (int k = 0; k <2000000; k ++) {synchronized (o) {si ++; object temp = o; for (int m = 0; m <10; m ++) {o = new Object ();} o = temp ;}} flag. incrementAndGet ();} Why is the above phenomenon: Code 1: After si performs the ++ operation (you can directly view the bytecode, which is not pasted here) There are several operations before putstatic, that is, we often call non-atomic operations. At this time, si is no longer the original object, so that the lock will become invalid for another thread, I think Code 3 and code 4 are the best evidence, and code 4 is more convincing. At that time, I was confused for a long time because I didn't see the expected situation. In fact, it is not very rigorous to use bytecode here. The best of course is the compilation code. If you have any questions, I hope you can correct them.