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!