Summary of multi-threaded synchronization locks synchronized (object locks and global locks)

1. The introduction of synchronized synchronization locks

/*
 * Not thread safe
 * */
//Multiple threads jointly access instance variables in an object, and there will be a "non-thread-safe" problem
class MyRunnable1 implements Runnable{
	private int num = 10;
	public void run() {
		try {
			if(num > 0) {
				System.out.println(""+Thread.currentThread().getName()+"开始"+",num= "+num--);
				Thread.sleep(1000);
				System.out.println(""+Thread.currentThread().getName()+"结束");
			}
		} catch (InterruptedException e) {
			e.printStackTrace ();
		}
	}
}public class Test5_5{
	public static void main(String[] args) {
		MyRunnable1 myRunnable1 =  new MyRunnable1();
		Thread thread1 = new Thread(myRunnable1,"线程1");
		Thread thread2 = new Thread(myRunnable1,"线程2");
		thread1.start();
		thread2.start();
	}
}

                          

The above example shows that two threads access an unsynchronized method at the same time. If the two threads operate the instance variables in the business object at the same time, there will be a "thread unsafe" problem.

From this we introduce the synchronized keyword to realize the synchronization problem:

In Java, use the synchronized keyword to control thread synchronization, to control synchronized code segments not to be executed by multiple threads at the same time, synchronized can be used in methods or in code blocks.

2.  Object lock

( 1) synchronized method (locks the current object)

If we modify the above code, add the synchronized keyword to the run() method to make it a synchronized method.

/*
 * Synchronization method
 * */
class MyRunnable1 implements Runnable{
	private int num = 10;
	public void run() {
		this.print();
	}

	public synchronized void print() {
		if(this.num > 0) {
			System.out.println(""+Thread.currentThread().getName()+"开始"+",num= "+num--);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace ();
			}
			System.out.println(""+Thread.currentThread().getName()+"结束");
		}
	}
}public class Test5_5{
	public static void main(String[] args) {
		MyRunnable1 myRunnable1 =  new MyRunnable1();
		Thread thread1 = new Thread(myRunnable1,"线程1");
		Thread thread2 = new Thread(myRunnable1,"线程2");
		thread1.start();
		thread2.start();
	}
}    

                       

Conclusion: If two threads access synchronized methods in the same object at the same time, it must be thread-safe.

( 2) synchronized code block (locking an object)

If you want to use a synchronized code block, you must set an object to be locked, so you can generally lock the current object : this.

/*
 * Synchronized code block
 * */
class MyRunnable1 implements Runnable{
	private int num = 10;
	public void run() {
		try {
			synchronized (this) {
				if(num > 0) {
					System.out.println(""+Thread.currentThread().getName()+"开始"+",num= "+num--);
					Thread.sleep(1000);
					System.out.println(""+Thread.currentThread().getName()+"结束");
				}	
			}
		} catch (InterruptedException e) {
			e.printStackTrace ();
		}
	}
}

public class Test5_5{
	public static void main(String[] args) {
		MyRunnable1 myRunnable1 =  new MyRunnable1();
		Thread thread1 = new Thread(myRunnable1,"线程1");
		Thread thread2 = new Thread(myRunnable1,"线程2");
		thread1.start();
		thread2.start();
	}
}  

                          

( 3) synchronized lock multiple objects

/*
 * synchronized lock multiple objects
 * */
class Sync{
	public synchronized void print() {
		System.out.println("print方法开始:"+Thread.currentThread().getName());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
		System.out.println("print方法结束"+Thread.currentThread().getName());
	}
}
class MyThread extends Thread{
	public void run() {
		Sync sync =  new Sync();
		sync.print();
	}
}
public class Test5_5{
	public static void main(String[] args) {
		for(int i = 0; i < 3;i++) {
			Thread thread = new MyThread();
			thread.start();
		}
	}
}
                      

According to the above example, we can find that synchronization cannot be achieved when synchronized locks multiple objects. From this, it can be concluded that the locks obtained by the keyword synchronized are all object locks, rather than a piece of code or method (function) as a lock . Which thread executes the method with the synchronized keyword or the synchronized code block first, which thread has the lock held by the method or the code block, and other threads can only appear in the waiting state, provided that multiple threads access the same object.

Only the read and write of shared resources need to be synchronized. If it is not a shared resource, then no synchronization operation is required.

3. Global lock

There are two ways to implement a global lock:

(1)  Use the synchronized keyword on static methods

Adding synchronized to a static static method locks the Class class, and adding synchronized to a non-static method locks the object. Class locks work on all object instances of the class.

/*
 * synchronized is used on static methods
 * */
class Sync{
	static public synchronized void print() {
		System.out.println("print方法开始:"+Thread.currentThread().getName());
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace ();
		}
		System.out.println("print方法结束"+Thread.currentThread().getName());
	}
}
class MyThread extends Thread{
	public void run() {
		Sync.print();
	}
}
public class Test5_5{
	public static void main(String[] args) {
		for(int i = 0; i < 3;i++) {
			Thread thread = new MyThread();
			thread.start();
		}
	}
}

                     

(2)  Use synchronized to lock the Class object of the class

The synchronized(class) block works the same as the synchronized static method.

/*
 * synchronized locks the Class object of the class
 * */
class Sync{
	public void print() {
		synchronized (Sync.class) {
			System.out.println("print方法开始:"+Thread.currentThread().getName());
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace ();
			}
			System.out.println("print方法结束"+Thread.currentThread().getName());
		}
	}
}
class MyThread extends Thread{
	public void run() {
		Sync sync =  new Sync();
		sync.print();
	}
}
public class Test5_5{
	public static void main(String[] args) {
		for(int i = 0; i < 3;i++) {
			Thread thread = new MyThread();
			thread.start();
		}
	}
}
                         


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326069005&siteId=291194637