Home  >  Article  >  Java  >  Java: Detailed explanation of object lock "synchronized" and global lock

Java: Detailed explanation of object lock "synchronized" and global lock

php是最好的语言
php是最好的语言Original
2018-08-03 11:20:252667browse

Let’s look at a piece of code first:

class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			System.out.println(Thread.currentThread().getName() + "开始执行");
			System.out.println("count还剩" + --count);
			System.out.println(Thread.currentThread().getName() + "执行结束");
			System.out.println();
		}
	}	
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

The running results are as follows:

Thread-0开始执行
Thread-2开始执行
Thread-1开始执行
count还剩8
count还剩9
Thread-2执行结束
count还剩7
Thread-1执行结束

Thread-1开始执行

Thread-0执行结束

Thread-0开始执行
count还剩5
Thread-0执行结束

Thread-2开始执行
count还剩4
Thread-2执行结束

Thread-2开始执行
count还剩3
count还剩6
Thread-2执行结束

Thread-2开始执行
Thread-0开始执行
count还剩2
Thread-2执行结束

Thread-2开始执行
count还剩0
Thread-2执行结束

Thread-1执行结束

count还剩1
Thread-0执行结束

Obviously this is not the result we want. The result we want is: a complete press alone Run your own run() method sequentially, but the above result is out of order: the second thread has come in before the previous thread has finished running its own task. So how to solve this problem?

First of all, let’s analyze that three threads get the object myThread we created at the same time, and then start these three threads. These three threads will enter the run() method at the same time for execution. If we want each thread to complete its task after entering, we need to lock the myThread object and prevent other threads from getting it. This can be achieved. For example, if there is a room, after you enter it, if you don't want others to come in again, you have to lock the door.

In Java, we are provided with a lock called "synchronized". So how should it be used?

Two modes of "synchronized": synchronized method and synchronized code block.

1. Object lock:

1. Synchronized code block: Add synchronized (the object to be locked) in front of the code block.

class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		synchronized (this) {
			while(count > 0) {
				System.out.println(Thread.currentThread().getName() + "开始执行");
				System.out.println("count还剩" + --count);
				System.out.println(Thread.currentThread().getName() + "执行结束");
				System.out.println();
			}
		}	
	}	
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

2. Synchronous method: Add the synchronized keyword in front of the return value of the method.

class MyThread implements Runnable{
	private int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			count--;
			fun();
		}
	}
	public synchronized void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

2. Global lock:

In the above, what we lock are myThread objects. What if we want to lock the same method of multiple objects?

There are also two methods with object locks: synchronization method and synchronization code block.

1. In the brackets before the synchronization code block, write the class of the method you want to lock. class

class MyThread implements Runnable{
	private static int count = 10;
	@Override
	public void run() {
		synchronized (MyThread.class) {
			while(count > 0) {
				count--;
				fun();
			}
		}	
	}
	public void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

2. On the basis of the synchronization method mentioned above, add the static keyword , you can achieve global lock.

class MyThread implements Runnable{
	private static int count = 10;
	@Override
	public void run() {
		while(count > 0) {
			fun();
		}
	}
	public synchronized static void fun() {
		System.out.println(Thread.currentThread().getName() + "开始执行");
		System.out.println("count还剩" + count);
		System.out.println(Thread.currentThread().getName() + "执行结束");
		System.out.println();
		count--;
	}
}

public class Test{
	public static void main(String[] args) {
		MyThread myThread = new MyThread();
		new Thread(myThread).start();
		new Thread(myThread).start();
		new Thread(myThread).start();
	}
}

Related articles:

Java synchronization lock (synchronized) sample code sharing

Detailed explanation of the deadlock of the synchronized keyword in Java and memory usage issues

Related videos:

Comprehensive analysis of Java annotations

The above is the detailed content of Java: Detailed explanation of object lock "synchronized" and global lock. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn