synchronized 锁

1. synchronized usefulness

When learning of the operating system, we will often hear deadlock, mutex and other terms, we know that this is some limited access to resources in multiple threads caused. Similarly, in javamulti-threaded programming, these threads are often at the same time to access a resource, the resource here we can be specific to a variable, an object, a piece of code blocks, even a class. So how to make these threads to access those resources in accordance with our expectations, we must use the keyword synchronizedto access code snippets to protect resources. Thus, when other tasks or threads that want to access the protected code block, first check whether the lock is available, and if Acquires the lock, then the code until the code is finished, in order to release the lock. During the lock code gets executed this thread protected, any other thread wants to access the code block, all will be blocked until the lock is released. So we can use keyword synchronizedrules with <thinking in java> in this book can be summed up:

If you are writing a variable that may next be read by another thread, or is reading a variable that has been written on another thread, you must use synchronization, and must be read with the same thread monitor lock synchronization.

2. synchronized usage

Now that the synchronizedrole of keywords, then the next we learn about synchronizedkeywords which resources can be protected and how to act on these resources. Here too, we divided into six kinds of situations.

2.1 two threads simultaneously access an object's synchronized method

Here we see a demo:

package SynchronizedDemo;

import java.util.concurrent.TimeUnit;
public class SameThreadSync implements Runnable{ @Override public void run() { synchronized (this) { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } } } 
package SynchronizedDemo;

public class MainThread { public static void main(String[] args) { SameThreadSync runnable = new SameThreadSync(); Thread thread1 = new Thread(runnable, "Amy thread"); Thread thread2 = new Thread(runnable, "Bob thread"); System.out.println("currentTime: " + System.currentTimeMillis()); thread1.start(); thread2.start(); } } 

Then we run it, look at the results:

currentTime: 1547988932743
currentTime: 1547988935744  Amy thread has finished now
currentTime: 1547988938748  Bob thread has finished now

As can be seen, Bob thread is executed, it starts executing the thread Amy. In addition, if we put synchronized(this)into another way to write the result is the same.

package SynchronizedDemo;

import java.util.concurrent.TimeUnit;
public class SameThreadSync implements Runnable{ @Override public synchronized void run() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } } 

Because the synchronizedblock must be given a synchronization object on it, and the most reasonable way is to use the current object whose method is being invoked: synchronized(this)So we both lock code format is the same object, that is, the current object. Therefore, according to synchronizedthe definition of this keyword, the lock is released only when the current object, and another thread to access the object.

When I removed the synchronization synchronized(this)time, then run again, the results are as follows:

currentTime: 1547989082259
currentTime: 1547989085265  Amy thread has finished now
currentTime: 1547989085265  Bob thread has finished now

This time, we found Boband Amyalmost complete at the same time.

2.2 two threads access a synchronization method of two objects

package SynchronizedDemo;

public class MainThread { public static void main(String[] args) { SameThreadSync runnable = new SameThreadSync(); SameThreadSync runnable2 = new SameThreadSync(); Thread thread1 = new Thread(runnable, "Amy thread"); Thread thread2 = new Thread(runnable2, "Bob thread"); System.out.println("currentTime: " + System.currentTimeMillis()); thread1.start(); thread2.start(); } } 

Results are as follows:

currentTime: 1547990419528
currentTime: 1547990422533  Bob thread has finished now
currentTime: 1547990422533  Amy thread has finished now

It found that two threads at the same time almost complete, and the second thread to complete more than the first thread. Because the synchronizedlock is the object that is currently running at a time Amyand Bobare running two different objects, it does not appear after a thread waits for another thread releases the lock to perform. Otherwise occur Bobthan Amybefore the end, this is not difficult to understand, when Amythe thread sleepwhen after Amya thread goes to sleep, cpugive Bobthe thread, when Amyafter a thread sleep, cpunot come and give Amy, Bobsleep well, on the first execution of the Bobthreads print statements.

Summary : Lock ordinary method, equivalent to the lock on the object's current call.

2.3 two threads access a static method of synchronized

We modify the class SameThread.javamethod, and in class MainThread.javais still created two different objects.

package SynchronizedDemo;

import java.util.concurrent.TimeUnit;
public class SameThreadSync implements Runnable{ @Override public void run() { method(); } private synchronized static void method() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } } 

Run the following results:

currentTime: 1547991444723
currentTime: 1547991447729  Amy thread has finished now
currentTime: 1547991450734  Bob thread has finished now

Why this Bobthread to wait Amyafter the completion of the thread, in order to enforce it? Because this is a static method belonging to a class, so a static method lock, is a lock for this class, so access to this class can only be accessed by a thread at the same time, so Bobhave to wait Amyafter the release of the lock of this class, to access the class.

If we synchronized staticreplaced synchronized(SameThread.class)a look at it?

currentTime: 1547991699001
currentTime: 1547991702005  Amy thread has finished now
currentTime: 1547991705006  Bob thread has finished now

We found the same results.

Summary : Lock to lock the static method is equivalent to the current class.

2.4 Non-simultaneous access synchronization method and a synchronization method

package SynchronizedDemo;

import java.util.concurrent.TimeUnit;
public class SameThreadSync implements Runnable{ @Override public void run() { if (Thread.currentThread().getName().equals("Amy thread")) { method1(); } else if (Thread.currentThread().getName().equals("Bob thread")) { method2(); } } private synchronized void method1() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } private void method2() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } } 
package SynchronizedDemo;

public class MainThread { public static void main(String[] args) { SameThreadSync runnable = new SameThreadSync(); Thread thread1 = new Thread(runnable, "Amy thread"); Thread thread2 = new Thread(runnable, "Bob thread"); System.out.println("currentTime: " + System.currentTimeMillis()); thread1.start(); thread2.start(); } } 

Run the following results:

currentTime: 1547992475217
currentTime: 1547992478219  Bob thread has finished now
currentTime: 1547992478219  Amy thread has finished now

Almost two threads simultaneously ended. So, if a member variable of a class, when multiple access methods are written, while the object of this class may be held by multiple threads, then the safest approach is to this member variable is set to private, At the same time all the methods of this variable write access should use the synchronizedkeyword protected.

Summary : synchronizedThe method does not block another thread with a non-object synchronizedmethod call in.

Ordinary different synchronization methods to access the same object 2.5

We will in the example above method2()method also add synchronizedkeywords, run a code:

currentTime: 1547992878720
currentTime: 1547992881726  Amy thread has finished now
currentTime: 1547992884730  Bob thread has finished now

The results also demonstrate the protection of a member variable method on a say. If one thread Ato access an object of synchronizedkey protection method, the other threads Bmust wait for the thread Aafter the release of the lock in order to access other synchronizedmethods.

2.6 simultaneously access a static synchronized and non-synchronized static method

package SynchronizedDemo;

import java.util.concurrent.TimeUnit;
public class SameThreadSync implements Runnable{ @Override public void run() { if (Thread.currentThread().getName().equals("Amy thread")) { method1(); } else if (Thread.currentThread().getName().equals("Bob thread")) { method2(); } } private synchronized static void method1() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } private synchronized void method2() { try { TimeUnit.MILLISECONDS.sleep(3000L); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("currentTime: " + System.currentTimeMillis() + " " + Thread.currentThread().getName() + " has finished now"); } } 

operation result:

currentTime: 1547993122882
currentTime: 1547993125888  Amy thread has finished now
currentTime: 1547993125888  Bob thread has finished now

Both are found almost run simultaneously, and why? Because the method1()method is a static method, and static methods are class level, we have said above, the lock of a static method, similar synchronized(xx.class), indicating that the lock of the object is .classan object, and method2()lock this general approach, we equivalent synchronized(this), indicating the lock is currently running instance of an object, that is method1(), and method2()the lock is not the same object, so the two are not affect each other.

Summary: lock static method, the lock classobject is locked to the conventional method, the object lock is an example of the current class, both not affect each other.

3. synchronized core idea

  • A lock can only be one thread simultaneously acquired, did not get the lock thread must wait

  • Each instance has its own corresponding to a lock, independently of each other between different instances; exception: the lock object is *.classas well synchronizeda modified staticmethod, when the class of all objects share the same lock.

  • Whether it is the normal method of execution or completion method throws an exception, will release the lock.



Author: rain ghost town
link: https: //www.jianshu.com/p/bd3ba6b9431a
Source: Jane book
Jane book copyright reserved by the authors, are reproduced in any form, please contact the author to obtain authorization and indicate the source.

Guess you like

Origin www.cnblogs.com/hanwuxing/p/11362077.html