1. Introduction
We all know that, for example, Java sells tickets, such as 10 tickets. If there is no lock, each thread sells 10 tickets, which is unreasonable
2. Error demonstration
Multithreading executes the same thing, without locking, there will be errors
package restudy; public class MyRunnable implements Runnable { int ticket = 20; public void run() { while (true) { sale(); } } public void sale() { if (ticket > 0) { try { Thread.sleep(500); } catch (InterruptedException e) { // The catch block automatically generated by TODO e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "------" + ticket); ticket--; } } }
package restudy; public class demo1 { public static void main(String[] args) { MyRunnable run = new MyRunnable(); Thread mt1 = new Thread(run); Thread mt2 = new Thread(run); Thread mt3 = new Thread(run); mt1.start(); mt2.start(); mt3.start(); } }
Thread-1------20
Thread-0------20
Thread-2------18
Thread-0------17
Thread-1------17
Thread-2------17
Thread-1------14
Thread-2------14
Thread-0------14
Thread-1------11
Thread-2------11
Thread-0------11
Thread-2------8
Thread-1------8
Thread-0------8
Thread-1------5
Thread-2------5
Thread-0------5
Thread-0------2
Thread-1------2
Thread-2------2
Thread-1-------1
This is obviously unreasonable. Some threads have been executed, and that thread has been executed again
3. Sync code block
- Synchronized code block: the synchronized keyword can be used in a block in the method to indicate that only the resources in this block are mutually exclusive. Format:
Synchronized (synchronization lock){ Code requiring synchronization }
-
be careful:
- With the lock object in the code block, you can use any object
- However, it must be ensured that the lock object used by multiple threads is the same
- Lock object function: lock the synchronization code block, and only one thread can execute in the synchronization code block
-
Idea: in a thread, an object can be defined initially, which can be any object, and it can be locked with synchronized. When multiple threads execute together, the same object will be used to lock
package restudy; public class MyRunnable implements Runnable { int ticket = 20; Object lock = new Object(); public void run() { while (true) { //A way to live synchronized (lock) { sale(); } } } public void sale() { if (ticket > 0) { try { Thread.sleep(500); } catch (InterruptedException e) { // The catch block automatically generated by TODO e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "------" + ticket); ticket--; } } }
package restudy; public class demo1 { public static void main(String[] args) { MyRunnable run = new MyRunnable(); Thread mt1 = new Thread(run); Thread mt2 = new Thread(run); Thread mt3 = new Thread(run); mt1.start(); mt2.start(); mt3.start(); } }
Thread-0------20
Thread-2------19
Thread-2------18
Thread-1------17
Thread-2------16
Thread-0------15
Thread-2------14
Thread-1------13
Thread-1------12
Thread-2------11
Thread-2------10
Thread-0------9
Thread-2------8
Thread-1------7
Thread-2------6
Thread-0------5
Thread-2------4
Thread-1------3
Thread-2------2
Thread-0------1
4. Synchronization method
public synchronized void method name (){ Code that may cause thread safety problems }
package restudy; public class MyRunnable implements Runnable { int ticket = 20; public void run() { while (true) { sale(); } } //Method add lock public synchronized void sale() { if (ticket > 0) { try { Thread.sleep(500); } catch (InterruptedException e) { // The catch block automatically generated by TODO e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "------" + ticket); ticket--; } } }
package restudy; public class demo1 { public static void main(String[] args) { MyRunnable run = new MyRunnable(); Thread mt1 = new Thread(run); Thread mt2 = new Thread(run); Thread mt3 = new Thread(run); mt1.start(); mt2.start(); mt3.start(); } }
Thread-0------20
Thread-0------19
Thread-2------18
Thread-1------17
Thread-2------16
Thread-0------15
Thread-2------14
Thread-2------13
Thread-1------12
Thread-2------11
Thread-0------10
Thread-2------9
Thread-1------8
Thread-2------7
Thread-0------6
Thread-2------5
Thread-1------4
Thread-2------3
Thread-0------2
Thread-2------1
5. Lock lock
Use steps:
- Create a ReentrantLock object in the member location
- Call lock() method before code that may have thread safety problems.
- Call the unlock() method after code that may have thread safety problems.
package restudy; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class MyRunnable implements Runnable { int ticket = 20; Lock l=new ReentrantLock();//Create Lock object public void run() { while (true) { l.lock();//Lock up sale();//Execution code l.unlock();//Release lock } } public void sale() { if (ticket > 0) { try { Thread.sleep(500); } catch (InterruptedException e) { // The catch block automatically generated by TODO e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "------" + ticket); ticket--; } } }
package restudy; public class demo1 { public static void main(String[] args) { MyRunnable run = new MyRunnable(); Thread mt1 = new Thread(run); Thread mt2 = new Thread(run); Thread mt3 = new Thread(run); mt1.start(); mt2.start(); mt3.start(); } }
Thread-0------20
Thread-1------19
Thread-2------18
Thread-0------17
Thread-1------16
Thread-2------15
Thread-0------14
Thread-1------13
Thread-2------12
Thread-0------11
Thread-1------10
Thread-2------9
Thread-0------8
Thread-0------7
Thread-1------6
Thread-2------5
Thread-0------4
Thread-1------3
Thread-2------2
Thread-0------1