Article directory
- Program, process, thread
- Thread safety
- To solve the problem of thread safety (to realize Runnable) -- synchronous code block
- To solve the problem of thread safety (to realize Runnable) -- synchronization method
- To solve the Thread safety problem (inherit Thread) - synchronous code block
- Solving Thread safety problem (inherit Thread) - synchronization method
- The third way to solve the thread safety problem: Lock lock -- new in JDK 5.0
- Similarities and differences between Synchronized and Lock
Program, process, thread
Program: a set of instructions written in a certain language to complete a specific task. That is, a static code, a static object. Process: an execution process generated by a program, or a running program. Is a dynamic process: by itself The process of emergence, existence and extinction - life cycle. >For example: QQ in operation, MP3 player in operation >Program is static, process is dynamic >As the unit of resource allocation, the system will match different memory areas for each process at runtime Thread: a process can be further refined into a thread, which is an execution path within a program. >If a process executes multiple threads simultaneously, it supports multiple threads >As the smallest unit of process scheduling and execution, each thread has its own running stack and program counter (pc). The cost of thread switching is small >Multiple threads in a process share the same memory unit / memory address space - > they allocate objects from the same heap. They can access the same Variables and objects. This makes the communication between threads more convenient and efficient. However, system resources shared by multiple threads may bring security risks.
Create thread
1. How to create threads -1: Inherit Thread class (Thread class implements Runnable interface) -2: Implement the Runnable interface (recommended). Class implements the interface, and can inherit other classes. Interfaces are implemented in multiple ways. Inheritance is single inheritance.) ---------------------------------------- Inherit Thread class: public class ThreadA extends Thread{ //Override run method @Override public void run(){ } } To implement the Runnable interface: public class ThreadA implements Runnable{ //Override run method @Override public void run(){ } }
Startup thread
1. Call the start() method of the thread. Note: calling the start() method is the real starting thread, while calling the run() method is equivalent to A normal method was called and the thread could not be started. ------------------------------------------------------- Inherited Thread start Thread mode: ThreadA t = new ThreadA(); t.start(); To implement the start thread mode of the Runnable interface: /** *Methods in Thread class * ThreadA t1= new Thread(Runnable target) */ ThreadA t = new Thread(new ThreadA()); t.start();
Thread safety
-
Reasons for thread safety
1. The uncertainty of multi thread execution causes the instability of execution results 2. For example, the sharing of ledgers by multiple threads will cause incomplete operations and damage data
As shown in the figure below, the original balance of the account is 3000 yuan. A and B withdraw 2000 yuan from the account at the same time (concurrently), and the account balance becomes - 1000 yuan. This problem is thread safety.
-
Solving thread safety problem -- thread synchronization
Mode 1: synchronize code blocks 1. Synchronous monitor, commonly known as lock. Any object of a class can act as a lock, requiring multiple threads to share the same lock 2. The synchronization monitor can be: current class. Class (Class clazz = current class. class(), class is loaded only once, So the object created in this way is unique), other class objects, this (object of current class) 3. In the way of inheriting Thread class to create multithreading, be careful to use this (current object) as synchronization monitor (ensure) 4. In the way of implementing Runnable interface to create multithreading, we can consider using this as synchronization monitor Synchronized (synchronization monitor){ //Code to be synchronized (code to operate shared data, such as the number of train tickets). The synchronized code cannot contain less or more } Mode 2: synchronization method Advantages: solve the problem of thread safety Disadvantage: when synchronizing code. Only one thread can participate, and other threads wait. It is a single thread process with low efficiency 1. If the code that operates on shared data is fully declared in a method, we might as well declare this method as a synchronous method 2. Summary: (1) The synchronization method still involves the synchronization monitor, but we do not need to display the declaration (2) Non static synchronization method, the synchronization monitor is this; Static synchronization method, synchronization monitor is: the current class itself (class. class).
To solve the problem of thread safety (to realize Runnable) -- synchronous code block
public class ThreadA implements Runnable{ private int ticket = 100; /** * Correct way */ //Object obj = new Object(); @Override public void run() { //Wrong way to create multiple Object objects //Object obj = new Object(); while (true){ //Wrong way to create multiple Object objects //synchronized(new Object()) { //synchronized(ThreadA .class) { synchronized(this) { //Share a lock //synchronized(obj) { if (ticket > 0) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ":Buy a ticket with the ticket number" + ticket); ticket--; } else { break; } } } } public static void main(String[] args) { ThreadA t = new ThreadA(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.setName("Window 1"); t2.setName("Window 2"); t3.setName("Window 3"); t1.start(); t2.start(); t3.start(); } }
To solve the problem of thread safety (to realize Runnable) -- synchronization method
The synchronization monitor of the synchronization method is this
public class ThreadC implements Runnable{ private int ticket = 100; @Override public void run() { while (true){ sellTicket(); } } //Synchronization method, decorated with the keyword synchronized private synchronized void sellTicket(){ if(ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ",Ticket number:" + ticket); ticket--; } } public static void main(String[] args) { ThreadC t = new ThreadC(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.setName("Window 1"); t2.setName("Window 2"); t3.setName("Window 3"); t1.start(); t2.start(); t3.start(); } }
To solve the Thread safety problem (inherit Thread) - synchronous code block
public class ThreadB extends Thread{ private int ticket = 100; //Correct way //private Object obj = new Object(); @Override public void run() { while (true){ synchronized (ThreadB.class){ //Correct way // synchronized (obje) {/ / correct way // synchronized (this) {/ / there will be errors in this mode if(ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+",Ticket number:"+ticket); ticket--; }else{ break; } } } } public static void main(String[] args) { ThreadB t = new ThreadB(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.setName("Window 1"); t2.setName("Window 2"); t3.setName("Window 3"); t1.start(); t2.start(); t3.start(); } }
To solve the Thread safety problem (inherit Thread) - synchronization method
public class ThreadD extends Thread{ private int ticket = 100; @Override public void run() { while (true){ sellTicket(); } } //private synchronized void sellTicket() {/ / error resolution private static synchronized void sellTicket(){ // Monitor is thread.class if(ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + ",Ticket number:" + ticket); ticket--; } } public static void main(String[] args) { ThreadD t = new ThreadD(); Thread t1 = new Thread(t); Thread t2 = new Thread(t); Thread t3 = new Thread(t); t1.setName("Window 1"); t2.setName("Window 2"); t3.setName("Window 3"); t1.start(); t2.start(); t3.start(); } }
The third way to solve the thread safety problem: Lock lock - New in JDK5.0
class Window implements Runnable{ private int ticket = 100; /** * Instantiation lock * Parameter fair(boolean): * true-Fair competition lock * false(Default) - random contention lock * When multithreading is implemented by inheritance, since multiple objects are created, lock needs to be set to static to class level to ensure the uniqueness of locks */ private ReentrantLock lock = new ReentrantLock(); @Override public void run() { while (true){ try { //Locking ensures that the following code is single threaded lock.lock(); if(ticket > 0){ try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+",Ticket number:"+ticket); ticket--; }else { break; } } finally { //Unlock lock.unlock(); } } } } public class LockTest { public static void main(String[] args) { Window w = new Window(); Thread t1 = new Thread(w); Thread t2 = new Thread(w); Thread t3 = new Thread(w); t1.setName("Window 1"); t2.setName("Window 1"); t3.setName("Window 1"); t1.start(); t2.start(); t3.start(); } }
Similarities and differences between Synchronized and Lock
The same: Both of them can solve the problem of thread safety Different: 1. Synchronized will automatically release the lock (synchronization monitor) after executing the corresponding synchronization code. 2. Lock requires us to add locks manually, call lock() method, and release locks manually, call unlock() method. 3. With Lock lock, the JVM will spend less time to schedule threads, and the performance is better. And it has better extensibility (providing more subclasses). Two methods are preferred: Lock → synchronize code block (has entered method body and allocated corresponding resources) → synchronize method (outside method body)