1. Synchronous problem raised
Thread synchronization is to prevent damage to data when multiple threads access a data object.
For example: both threads ThreadA and ThreadB operate the same Foo object and modify the data on the Foo object.
package cn.thread;public class Foo { private int x = 100; public int getX() { return x; } public int fix(int y) { x = x - y; return x; }} package cn.thread;public class MyRunnable implements Runnable { private Foo foo = new Foo(); public static void main(String[] args) { MyRunnable run = new MyRunnable(); Thread ta = new Thread(run, "Thread-A"); Thread tb = new Thread(run, "Thread-B"); ta.start(); tb.start(); } public void run() { for (int i = 0; i < 3; i++) { this.fix(30); try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + " : The x value of the current foo object = " + foo.getX()); } } public int fix(int y) { return foo.fix(y); }}Running results:
Thread-B: The x value of the current foo object = 40
Thread-A: The x value of the current foo object = 40
Thread-B: The x value of the current foo object = -20
Thread-A: The x value of the current foo object = -20
Thread-B: The x value of the current foo object = -80
Thread-A: The x value of the current foo object = -80
From the results, it was found that such output value was obviously unreasonable. The reason is that two threads access Foo objects without control and modify their data.
If you want to maintain the rationality of the results, you only need to achieve one goal, which is to restrict access to Foo, and only one thread can access it at a time. This will ensure the rationality of the data in the Foo object.
In the specific Java code, two operations need to be completed:
Identify the Foo variable x of the resource class that is visited by competition as private;
Synchronize the code that modifies the variables, and use the synchronized keyword to synchronize the method or code.
package cn.thread;public class Foo2 { private int x = 100; public int getX() { return x; } //Synchronized method public synchronized int fix(int y) { x = x - y; System.out.println("Thread"+Thread.currentThread().getName() + "Run ends, reduce "" + y + "", the current value is: " + x); return x; } // // Synchronized code block// public int fix(int y) {// synchronized (this) {// x = x - y;// System.out.println("thread"+Thread.currentThread().getName() + "Run ends, reduce "" + y// + "", the current value is: " + x);// }// // return x;// }} package cn.thread;public class MyRunnable2 { public static void main(String[] args) { MyRunnable2 run = new MyRunnable2(); Foo2 foo2=new Foo2(); MyThread t1 = run.new MyThread("Thread A", foo2, 10); MyThread t2 = run.new MyThread("Thread B", foo2, -2); MyThread t3 = run.new MyThread("Thread C", foo2, -3); MyThread t4 = run.new MyThread("Thread D", foo2, 5); t1.start(); t2.start(); t3.start(); t4.start(); } class MyThread extends Thread { private Foo2 foo2; /**Current value*/ private int y = 0; MyThread(String name, Foo2 foo2, int y) { super(name); this.foo2 = foo2; this.y = y; } public void run() { foo2.fix(y); } }} Thread A run ends, reduces "10", the current value is: 90
Thread C runs and ends, reduces "-3", the current value is: 93
Thread B runs at the end, reduces "-2", the current value is: 95
Thread D runs and ends, reduces "5", the current value is: 90
2. Synchronization and locking
1. The principle of lock
Each object in Java has a built-in lock.
When the program runs on a non-static synchronized synchronization method, the lock associated with the current instance of the code class being executed (this instance). A lock that acquires an object is also called acquiring lock, locking an object, locking on an object, or syncing on an object.
The object lock only works when the program runs to a synchronized synchronization method or code block.
There is only one lock for an object. So, if a thread acquires the lock, no other thread can acquire the lock until the first thread releases (or returns) the lock. This also means that no other thread can enter the synchronized method or code block on the object until the lock is released.
Releasing a lock means that the lock thread exits the synchronized synchronization method or code block.
There are a few key points about locking and synchronization:
1) Only methods can be synchronized, but variables and classes cannot be synchronized;
2) Each object has only one lock; when it comes to synchronization, what should be clear on? That is, on which object is synchronized?
3) There is no need to synchronize all methods in the class. Classes can have both synchronous and asynchronous methods.
4) If two threads want to execute the synchronized method in one class, and the two threads use the same instance to call the method, then only one thread can execute the method at a time, and the other needs to wait until the lock is released. That is: if a thread acquires a lock on an object, no other thread can enter any synchronization method in the class (of that object).
5) If the thread has synchronization and asynchronous methods, the asynchronous methods can be freely accessed by multiple threads without being restricted by locks.
6) When the thread sleeps, no lock it holds will be released.
7) Threads can obtain multiple locks. For example, calling the synchronization method of another object in the synchronization method of one object will acquire the synchronization lock of the two objects.
8) Synchronization impairs concurrency and should narrow the synchronization range as much as possible. Synchronization can not only synchronize the entire method, but also synchronize some code blocks in the method.
9) When using synchronization code blocks, you should specify which object to synchronize, that is, which object's lock is to be acquired. For example:
public int fix(int y) { synchronized (this) { x = x - y; } return x;} Of course, the synchronization method can also be rewritten as an asynchronous method, but the functions are exactly the same, for example:
public synchronized int getX() { return x++;} and
public int getX() { synchronized (this) { return x++; }}The effect is exactly the same.
3. Static method synchronization
To synchronize static methods, a lock is needed for the entire class object, which is this class (XXX.class).
For example:
public static synchronized int setName(String name){ Xxx.name = name;}
Equivalent to
public static int setName(String name){ synchronized(Xxx.class){ Xxx.name = name; }}4. What happens if the thread cannot obtain the lock
If the thread tries to enter a synchronous method and its lock has been occupied, the thread is blocked on the object. Essentially, a thread enters a pool of the object and must wait where it must wait until its lock is released and the thread becomes runable or run again.
When considering blocking, be sure to pay attention to which object is being used for locking:
1. Threads that call non-static synchronization methods in the same object will block each other. If it is a different object, each thread has its own object lock, and threads do not interfere with each other.
2. Threads that call static synchronization methods in the same class will block each other, and they are all locked on the same Class object.
3. Static synchronization methods and non-static synchronization methods will never block each other, because static methods are locked on Class objects, while non-static methods are locked on objects of this class.
4. For synchronized code blocks, you need to see clearly what objects have been used for locking (the contents of synchronized brackets after synchronized). Threads synchronized on the same object will block each other, and threads locked on different objects will never block each other.
5. When is the need to synchronize
When multiple threads access mutually exclusive (exchangeable) data simultaneously, it should be synchronized to protect the data, ensuring that both threads do not modify and change it at the same time.
For data that can be changed in non-static fields, non-static methods are usually accessed.
For data that can be changed in a static field, it is usually accessed using a static method.
The problem becomes very complicated if you need to use static fields in non-static methods, or call non-static methods in static fields. It has exceeded the scope of the SJCP exam.
6. Thread safety category
When a class is well synchronized to protect its data, this class is called "thread-safe".
Even for thread-safe classes, you should be very careful, because the threads that operate are still not necessarily safe.
7. Thread synchronization summary
1. The purpose of thread synchronization is to protect the damage to resources when multiple threads access a resource.
2. The thread synchronization method is implemented through locks. Each object has only one lock. This lock is associated with a specific object. Once the thread acquires the object lock, other threads accessing the object can no longer access other synchronization methods of the object.
3. For static synchronization methods, locks are for this class, and lock objects are Class objects of this class. The locks of static and non-static methods do not interfere with each other. A thread acquires a lock, and when accessing a synchronization method on another object in a synchronization method, it acquires these two object locks.
4. For synchronization, it is key to always be aware of which object to synchronize on.
5. When writing thread-safe classes, you need to always pay attention to making correct judgments on the logic and security of multiple threads competing to access resources, analyze the "atomic" operations, and ensure that other threads cannot access the competing resources during the atomic operation.
6. When multiple threads are waiting for an object lock, the thread that has not obtained the lock will block.
7. Deadlock is caused by threads waiting for each other to lock, and the probability of occurrence in reality is very small. If you really want to write a deadlock program, it may not be easy to use, haha. However, once a program dies, the program will die.
Original link: http://www.cnblogs.com/linjiqin/p/3208843.html
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.