Multi-threaded access to a resource at the same time can produce unpredictable results, so the resource is locked, the first thread that accesses the resource locks it, other threads cannot use that resource until the lock is lifted.
As an example:
Deposit 1000 yuan, can take out 800 when I took 800, when I also use two threads call this money operation, sometimes can take out 1600 yuan
Static class Hellorunable implements runnable{ private int money = +; Remove 800 yuan int getmoney () { System.out.println ("Start" + money); if (Money >) { try { thread.sleep], } catch (Interruptedexception e) { e.printstacktrace (); c9/>} money- =; System.out.println ("I took 800 yuan" + money); } System.out.println ("End" + money); return money; } @Override public Void Run () {Money = Getmoney (); } } public static void Main (string[] args) { hellorunable hellorunable = new hellorunable (); Thread t = new thread (hellorunable); thread T1 = new Thread (hellorunable); T.start (); T1.start (); }
Synchronized
So we introduced the synchronization mechanism, the Synchronized keyword is added before the method of taking money, which is called the synchronous method, and the output result is
Each object in Java has a lock, or monitor, that locks the object when a thread accesses the synchronized method of an object, and no other thread can access the object's Synchronized method. The object lock is not freed until the previous thread finishes executing the method, and the other thread can use the object's Synchronized method. Note: This is a lock on the object, and there is no limit relationship between objects if they are different objects.
If an object has multiple synchronized methods and a thread has entered the synchronized method at some point, the other thread is unable to access any of the synchronized methods of the object until the method has finished executing.
For example:
public static void Main (string[] args) {Example Example = new Example (); Thread T1 = new Thread1 (example); Thread t2 = new Thread2 (example); T1.start (); T2.start (); } static class Example {public synchronized void execute () {for (int i = 0; i < 20; + +) i) {try {thread.sleep (long) math.random () * 1000); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("Hello:" + i); }} public void Execute2 () {for (int i = 0; i <; ++i) { try {thread.sleep (long) math.random () * 1000); } catch (Interruptedexception e) {e.printstacktrace (); } SYstem.out.println ("World:" + i); }}}} Static class Thread1 extends Thread {private Example Example; Public Thread1 (Example Example) {this.example = Example; } @Override public void Run () {example.execute (); }} static Class Thread2 extends Thread {private Example Example; Public Thread2 (Example Example) {this.example = Example; } @Override public void Run () {example.execute2 (); } }
When synchronized is added, another synchronization method does not execute when the synchronization method is not completed
A static synchronization method
When a synchronized keyword-modified method is statically decorated, the non-static synchronization method locks the object, but the static method does not belong to the object, but belongs to the class, which locks the class object of the classes in which the method resides.
public static void Main (string[] args) {Example Example = new Example (); Thread T1 = new Thread1 (example); Example = new example (); Thread t2 = new Thread2 (example); T1.start (); T2.start (); } static class Example {public static synchronized void execute () {for (int i = 0; i < 20; ++i) {try {thread.sleep (long) math.random () * 1000); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("Hello:" + i); }} public static synchronized void Execute2 () {for (int i = 0; i <; ++i) {try {Thread.Sleep ((long) math.random () * 1000); } catch (Interruptedexception e) { E.printstacktrace (); } System.out.println ("World:" + i); }}}} Static class Thread1 extends Thread {private Example Example; Public Thread1 (Example Example) {this.example = Example; } @Override public void Run () {example.execute (); }} static Class Thread2 extends Thread {private Example Example; Public Thread2 (Example Example) {this.example = Example; } @Override public void Run () {example.execute2 (); } }
No static Method method:
When a synchronized method is static, when the thread accesses the method, it is not the object that the Synchronized method resides in, but the corresponding class object of the class in which the Synchronized method resides (in Java, No matter how many objects a class has, these objects will correspond to a unique class object, so when a thread accesses two static synchronized methods of two objects of a class, their order of execution is also sequential, that is, a thread executes first, executes the release lock, Another thread to execute again)
Synchronized code block
Synchronized (object) {
}
Indicates that the object object will be locked during execution (this object can be used for any class of objects or this), and can be self-defined for the locked object
public class Test {public static void main (string[] args) {Example Example = new Example (); Thread T1 = new Thread1 (example); Thread t2 = new Thread2 (example); T1.start (); T2.start (); }} class Example {Private Object object = new Object (); public void Execute () {System.out.println ("I started up"); Synchronized (object) {for (int i = 0; i <; ++i) {try {T Hread.sleep ((Long) math.random () * 1000); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("Hello:" + i); }}} public void Execute2 () {System.out.println ("I also started"); Synchronized (object) {for (int i = 0; i <; ++i) {try {T Hread.sleep ((Long) math.random () * 1000); } catch (Interruptedexception e) {e.printstacktrace (); } System.out.println ("World:" + i); }}}} class Thread1 extends Thread {private Example Example; Public Thread1 (Example Example) {this.example = Example; } @Override public void Run () {example.execute (); }} class Thread2 extends Thread {private Example Example; Public Thread2 (Example Example) {this.example = Example; } @Override public void Run () {example.execute2 (); } }
You can see that in addition to the methods in the synchronized code block, the others are not executed synchronously.
The synchronized method is a coarse-grained concurrency control where only one thread can execute the synchronized method at a time.
Synchronized blocks are fine-grained concurrency controls that only synchronize code in the block, and other code within the method can be accessed concurrently by multiple threads
Multithreaded Programming--Part 3 multi-thread sync->synchronized keywords