Article catalog
1, Thread synchronization
1. Ticket sales
- Case requirements
A cinema is currently showing domestic blockbusters, with a total of 100 tickets, and it has three windows for ticket sales. Please design a program to simulate the ticket sales of the cinema
- Implementation steps
Define a class SellTicket to implement the Runnable interface, which defines a member variable: private int tickets = 100;
Rewrite the run() method in SellTicket class to realize ticket selling. The code steps are as follows
If the number of votes is greater than 0, sell the tickets and tell which window it is sold
After selling the tickets, the total number of votes will be reduced by 1
The ticket is sold out and the thread stops
The selltimo class has the following test steps
Create an object of SellTicket class
Create three Thread class objects, take the SellTicket object as the parameter of the construction method, and give the corresponding window name
Start thread
- code implementation
public class SellTicket implements Runnable { private int tickets = 100; //Rewrite the run() method in SellTicket class to realize ticket selling. The code steps are as follows @Override public void run() { while (true) { if(ticket <= 0){ //out of stock break; }else{ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } ticket--; System.out.println(Thread.currentThread().getName() + "Selling tickets,Remaining" + ticket + "Ticket"); } } } } public class SellTicketDemo { public static void main(String[] args) { //Create an object of SellTicket class SellTicket st = new SellTicket(); //Create three Thread class objects, take the SellTicket object as the parameter of the construction method, and give the corresponding window name Thread t1 = new Thread(st,"Window 1"); Thread t2 = new Thread(st,"Window 2"); Thread t3 = new Thread(st,"Window 3"); //Start thread t1.start(); t2.start(); t3.start(); } }
2. Problems of ticket selling cases
- There is a problem selling tickets
- The same ticket appeared many times
- There were negative votes
- Causes of problems Due to the randomness of thread execution, the execution right of cpu may be lost during ticket selling, resulting in problems
3. Synchronize code blocks to solve data security problems
- Conditions for safety problems
Is a multithreaded environment
Shared data
Multiple statements operate on shared data
- How to solve the problem of multithreading security?
Basic idea: let the program have no security environment
- How?
Lock the code for multiple statements to operate the shared data, so that only one thread can execute at any time
Java provides a way to synchronize code blocks
- Sync code block format:
synchronized(Any object) { Code for multiple statements to operate on shared data }
- Synchronized (arbitrary object): it is equivalent to locking the code, and any object can be regarded as a lock
- Advantages and disadvantages of synchronization
- Benefits: it solves the data security problem of multithreading
- Disadvantages: when there are many threads, each thread will judge the lock on synchronization, which is very resource-consuming and will virtually reduce the running efficiency of the program
- Code demonstration
public class SellTicket implements Runnable { private int tickets = 100; private Object obj = new Object(); @Override public void run() { while (true) { synchronized (obj) { // Lock the code that may have security problems. Multiple threads must use the same lock //When t1 comes in, it will lock this code if (tickets > 0) { try { Thread.sleep(100); //t1 rest 100ms } catch (InterruptedException e) { e.printStackTrace(); } //Window 1 is selling ticket 100 System.out.println(Thread.currentThread().getName() + "The second is being sold" + tickets + "Ticket"); tickets--; //tickets = 99; } } //When t1 comes out, the lock of this code is released } } } public class SellTicketDemo { public static void main(String[] args) { SellTicket st = new SellTicket(); Thread t1 = new Thread(st, "Window 1"); Thread t2 = new Thread(st, "Window 2"); Thread t3 = new Thread(st, "Window 3"); t1.start(); t2.start(); t3.start(); } }
4. The synchronization method solves the problem of data security
- Format of synchronization method
Synchronization method: add the synchronized keyword to the method
Modifier synchronized Return value type method name(Method parameters) { Method body; }
- What is the lock object of the synchronization method? this
- Static synchronization method Synchronous static method: add the synchronized keyword to the static method
Modifier static synchronized Return value type method name(Method parameters) { Method body; }
- What is the lock object for synchronous static methods? Class name class
- Code demonstration
public class MyRunnable implements Runnable { private static int ticketCount = 100; @Override public void run() { while(true){ if("Window one".equals(Thread.currentThread().getName())){ //Synchronization method boolean result = synchronizedMthod(); if(result){ break; } } if("Window II".equals(Thread.currentThread().getName())){ //Synchronous code block synchronized (MyRunnable.class){ if(ticketCount == 0){ break; }else{ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } ticketCount--; System.out.println(Thread.currentThread().getName() + "Selling tickets,Remaining" + ticketCount + "Ticket"); } } } } } private static synchronized boolean synchronizedMthod() { if(ticketCount == 0){ return true; }else{ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } ticketCount--; System.out.println(Thread.currentThread().getName() + "Selling tickets,Remaining" + ticketCount + "Ticket"); return false; } } } public class Demo { public static void main(String[] args) { MyRunnable mr = new MyRunnable(); Thread t1 = new Thread(mr); Thread t2 = new Thread(mr); t1.setName("Window one"); t2.setName("Window II"); t1.start(); t2.start(); } }
5.Lock lock
Although we can understand the Lock object problem of synchronization code blocks and synchronization methods, we do not directly see where the Lock is added and where the Lock is released. In order to more clearly express how to add and release the Lock, JDK5 provides a new Lock object Lock
Lock is an interface that cannot be instantiated directly. Its implementation class ReentrantLock is used to instantiate it here
- ReentrantLock construction method

- Locking and unlocking method

- Code demonstration
public class Ticket implements Runnable { //Number of tickets private int ticket = 100; private Object obj = new Object(); private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while (true) { //synchronized (obj) {/ / multiple threads must use the same lock try { lock.lock(); if (ticket <= 0) { //out of stock break; } else { Thread.sleep(100); ticket--; System.out.println(Thread.currentThread().getName() + "Selling tickets,Remaining" + ticket + "Ticket"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } // } } } } public class Demo { public static void main(String[] args) { Ticket ticket = new Ticket(); Thread t1 = new Thread(ticket); Thread t2 = new Thread(ticket); Thread t3 = new Thread(ticket); t1.setName("Window one"); t2.setName("Window II"); t3.setName("Window three"); t1.start(); t2.start(); t3.start(); } }
6. Deadlock
- summary Thread deadlock refers to that two or more threads hold the resources required by each other, resulting in these threads being in a waiting state and unable to execute
- Under what circumstances will deadlock occur
- Limited resources
- Synchronous nesting
- Code demonstration
public class Demo { public static void main(String[] args) { Object objA = new Object(); Object objB = new Object(); new Thread(()->{ while(true){ synchronized (objA){ //Thread one synchronized (objB){ System.out.println("Well off students are walking"); } } } }).start(); new Thread(()->{ while(true){ synchronized (objB){ //Thread two synchronized (objA){ System.out.println("Xiao Wei is walking"); } } } }).start(); } }