On Multithreading

Posted by phparmy on Thu, 10 Feb 2022 03:38:38 +0100

1. Process? Thread? Multitasking?
In fact, there are a lot of cool programs in each process, such as cool browser, cool video, and so on. The thread is a branch or phenomenon in the process, which is an independent execution path. A process includes at least one thread. Threads can be understood as improving the efficiency of program operation, or performing their respective duties. For example, QQ can not only type and chat at the same time, but also voice. For example, when there are three lanes on the highway, vehicles can run at the same time, making full use of the road, which greatly improves the traffic efficiency.
2. How threads are created
Common Thread creation methods include Thread, Runnable, Callable and Thread pool.
Official description of Thread:

2.1 steps of thread creation:

.Custom thread class inheritance Thread
.rewrite run()Method to write the thread execution program body
.Create a thread object and call start()Method to start the thread.

2.1.1 MyThreadt test

package com.thread;

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <30 ; i++) {
            System.out.println("Child thread running:"+i);
        }
    }
}

package com.test;

import com.thread.MyThread;

public class CommonTest {
    public static void main(String[] args) {
    	//Custom thread
        MyThread myThread = new MyThread();
        myThread.start();

		//main thread
        for (int i = 0; i < 500; i++) {
            System.out.println("Main thread running:" + i);
        }
    }
}

2.1.2 multi thread downloading pictures
1. Import jar
2. Create download class
3. Custom thread class

 <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
package com.test;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * Custom download class
 */
public class WebDownload {
//Download method
    public void downloadFile(String url, String fileName) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(fileName));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("File download failed");
        }
    }

}

package com.thread;

import com.test.WebDownload;
//Multi thread synchronous downloading of pictures
public class DownloadThread extends Thread {
    //Network picture address
    private String url;
    //file name
    private String name;

    public DownloadThread(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        WebDownload webDownload = new WebDownload();
        webDownload.downloadFile(url, name);
        System.out.println("Downloaded file, file name:" + name);
    }

    public static void main(String[] args) {
        DownloadThread downloadThread=new DownloadThread("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e","zhangjianing");
        DownloadThread downloadThread2=new DownloadThread("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e","zhangjianing2");
        DownloadThread downloadThread3=new DownloadThread("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e","zhangjianing3");
        downloadThread.start();
        downloadThread2.start();
        downloadThread3.start();
    }
}

Download successful

2.2 steps to implement Runnable interface

  .Custom class implementation Runnable Interface
  .Implement in the interface run()Method, in which the thread execution body is written
  .Create a thread object and call start()method,Start the thread.

Interpretation of official documents:



2.2.1 RunableDemo

package com.runnable;
//Implement the Runnable interface, rewrite the run method,
public class MyRunnable implements Runnable {
    public void run() {//Thread core executor
        for (int i = 0; i < 20; i++) {
            System.out.println("Sub thread running:" + i);
        }
    }
}

public class CommonTest {
    public static void main(String[] args) {
        //Create the implementation class object of runnable interface
        MyRunnable myRunnable = new MyRunnable();
        //Thread itself also implements the Runnable interface.
        Thread thread = new Thread(myRunnable);
        //Call the start method to start the thread
        thread.start();
        for (int i = 0; i < 50; i++) {
            System.out.println("Main thread running:" + i);
        }
    }

The difference between inheriting Thread class and implementing Runnable interface

* inherit Thread class
1,Subclass inheritance Thread Class has multithreading capability
2,Start thread:Subclass object.start()
3,Not recommended:avoid OOP Limitations of single inheritance.
* realization Runable Interface
1,Implementation interface Runnable Multi threading capability
2,Start the thread and pass in the target object+Thread object.start()
3,Recommended use Runnable,It avoids the limitation of single inheritance, is flexible and convenient, and is convenient for the same object to be used by multiple threads.

2.2.2 multi threading to buy train tickets

package com.runnable;

//Implement the Runnable interface, rewrite the run method,
public class MyRunnable implements Runnable {
    //votes 
    private int ticket = 100;

    public void run() {//Thread core executor
        while (ticket>0) {
            System.out.println(Thread.currentThread().getName() + "Selling item" + ticket + "Ticket");
            //If each thread sells a ticket, one ticket will be deducted
            ticket--;
        }
    }
}

public class CommonTest {
    public static void main(String[] args) {
        //Thread 1 simulated ticket selling
        MyRunnable myRunnable = new MyRunnable();
        
        Thread thread = new Thread(myRunnable);
        thread.start();
        
        //Thread 2 simulated ticket selling
        Thread thread2 = new Thread(myRunnable);
        thread2.start();
        //Thread 3 simulated ticket selling
        Thread thread3 = new Thread(myRunnable);
        thread3.start();

        //Thread 4 simulated ticket selling
        Thread thread4 = new Thread(myRunnable);
        thread4.start();
    }

console output

Thread-0 The 100th ticket is on sale
Thread-0 Ticket 99 is on sale
Thread-0 The 98th ticket is on sale
Thread-0 The 97th ticket is on sale
Thread-0 Ticket 96 is on sale
Thread-0 Ticket 95 is on sale
Thread-0 Ticket 94 is on sale
Thread-3 The 100th ticket is on sale
Thread-1 The 100th ticket is on sale
Thread-1 Ticket 99 is on sale
Thread-1 The 98th ticket is on sale
Thread-1 The 97th ticket is on sale
Thread-1 Ticket 96 is on sale
Thread-1 Ticket 95 is on sale
Thread-1 Ticket 94 is on sale
Thread-1 Ticket 93 is on sale
Thread-1 Ticket 92 is on sale
Thread-2 The 100th ticket is on sale
Thread-1 Ticket 91 is on sale
Thread-3 Ticket 99 is on sale
Thread-0 Ticket 93 is on sale

At this time, a problem is found. Thread 0, thread 3 and thread 2 have all sold ticket No. 100, which indicates that when multiple threads operate a resource at the same time, the thread is unsafe and there are serious data problems. This problem will be solved later.

2.3 steps to implement Callable interface

1,realization Callable Interface,Return value type required
2,rewrite call Method, you need to throw an exception
3,Create target object
4,Create execution service: ExecutorService es=new Executors.newFixedThreadPool(1);
5,Submit for execution: Future<Boolean> result=es.submit(1);
6,Get results: boolean flag=result.get();
7,Shut down service:es.shutdownNow();

2.3.1 implement the Callable interface to download pictures through multiple threads

package com.test;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

/**
 * Custom download class
 */
public class WebDownload {
//Download method
    public void downloadFile(String url, String fileName) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(fileName));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("File download failed");
        }
    }

}

package com.callable;

import com.test.WebDownload;

import java.util.concurrent.Callable;

public class MyCallable implements Callable {
    private String url;
    private String name;

    public MyCallable(String url, String name) {
        this.url = url;
        this.name = name;
    }

    public Boolean call() throws Exception {
        //
        WebDownload webDownload = new WebDownload();
        //Download the file according to the file url and file name
        webDownload.downloadFile(url,name);
        return true;
    }
}

public class CommonTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        MyCallable myCallable = new MyCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e", "zhangjianing2021");
        MyCallable myCallable2 = new MyCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e", "zhangjianing2022");
        MyCallable myCallable3 = new MyCallable("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F24%2F20190124212555_aAzHh.thumb.700_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1620823150&t=52bd044f2ba560bfe9ca51bb1b07221e", "zhangjianing2023");

        //Create execution service
        ExecutorService es = Executors.newFixedThreadPool(3);

        //Submit for execution
        Future<Boolean> submit = es.submit(myCallable);
        Future<Boolean> submit2 = es.submit(myCallable2);
        Future<Boolean> submit3 = es.submit(myCallable3);

        //Get results
        boolean r = submit.get();
        boolean r2 = submit2.get();
        boolean r3 = submit3.get();
        //Shut down service
        es.shutdown();
    }

3. Thread state
Thread states are divided into five states: creation, ready, blocking, running and death.

//Thread execution order
Thread thread = new Thread();
1,Once a thread object is created, it enters a new state
2,call start()Method, the thread is in a ready state, but it does not mean to schedule execution immediately.
3,When called sleep(),wait()Or synchronous locking,The thread entered a blocking state. When the blockage is cleared,
	Re enter the ready state and wait cpu dispatch.
4,After entering the running state, the thread starts to execute business.
5,Thread death.


3.1 thread core method

		//Update thread priority
	   .setPriority(int newPriority);
	  //Hibernates the currently executing thread for the specified number of milliseconds
	   .static void sleep(long millis);
	   //Wait for this thread to terminate / merge threads
        .void join();
        //Pause the thread object currently executing,
        //And execute other threads, also known as thread comity
        .static void yield();
        //Interrupt the thread, try not to use this method.
        .void interrupt();
        //Test whether the thread is active
        .boolean isAlive()

3.1 stop / terminate threads
At present, it is not recommended to use the stop() and destroy() methods officially provided by JDK. The document indicates that this method has been abandoned.
More suggestions are to make the thread stop smoothly, such as setting flag bit termination variable.
Example:

public class StopRunnable implements Runnable {
    //Thread definition stop flag
    private boolean flag = true;

    //Provide external thread stopping method
    public void stop() {
        this.flag = false;
    }


    public void run() {
        int i =0;
        //Judgment mark in thread
        while (flag) {
            System.out.println(Thread.currentThread().getName()+"Run.....");
        }
    }
}
    public static void main(String[] args) {
        StopRunnable stopRunnable = new StopRunnable();

        Thread thread = new Thread(stopRunnable);

        thread.start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("Main thread:"+i);
            if(i==900){
                //Call the stop method to switch the identifier and stop the thread
                stopRunnable.stop();
                System.out.println(Thread.currentThread().getName()+":The thread stopped");
            }
        }
    }

3.2 thread hibernation

1,sleep(long millils)Specifies the number of milliseconds the current thread is blocking
2,sleep There is an exception InteruptedException;
3,sleep When the time reaches, the thread enters the waiting state
4,sleep Can simulate network delay,Countdown, etc.
5,Every object has a lock, but sleep The lock will not be released.

***Ticket selling simulation network delay case

public class Ticket implements Runnable {
	//votes 
    private static int ticket = 100;

    public void run() {
        while (ticket > 0) {
            try {
                //Analog delay 2s
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "Thread is selling" + ticket-- + "Ticket");
        }
    }

    public static void main(String[] args) {
        Ticket ticket = new Ticket();

        Thread thread = new Thread(ticket);
        Thread thread2 = new Thread(ticket);
        thread.start();
        thread2.start();
    }
}

****Simulation countdown case

//Simulation countdown Demo
public class CountdownTest implements Runnable {
    private static int num = 10;

    public void run() {
        while (num > 0) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("num>>>>>:" + num--);
        }
    }

    public static void main(String[] args) {
        CountdownTest countdownTest = new CountdownTest();
        Thread thread = new Thread(countdownTest);
        thread.start();
    }
}

num>>>>>:10
num>>>>>:9
num>>>>>:8
num>>>>>:7
num>>>>>:6
num>>>>>:5
num>>>>>:4
num>>>>>:3
num>>>>>:2
Disconnected from the target VM, address: '127.0.0.1:12167', transport: 'socket'
num>>>>>:1

3.3 comity

1,Comity thread, which suspends the thread currently executing, but does not block.
2,Change the thread from running state to ready state
3,Give Way cpu Reschedule,Comity may not succeed,see cpu Mood.

Thread comity Demo

package com.demo;

//Thread comity demo
public class YieldRunable implements Runnable {
    public void run() {
        System.out.println(Thread.currentThread().getName() + "The thread starts executing");
        Thread.yield();//Comity thread
        System.out.println(Thread.currentThread().getName() + "Thread stop execution");
    }

    public static void main(String[] args) {
        YieldRunable yieldRunable = new YieldRunable();

        Thread thread = new Thread(yieldRunable);
        thread.setName("A");

        Thread thread2 = new Thread(yieldRunable);
        thread2.setName("B");

        thread.start();
        thread2.start();
    }
}

3.4 Join merge thread

Join Merge thread,After the execution of this journey, other threads are blocked when executing other threads.
Like banks VIP,Or jump the queue. only vip After handling the business, ordinary users can do the business.

Merge thread Join cases

package com.demo;

public class JoinRunnable implements Runnable {

    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("Join>>>>>:" + i);
        }
    }


    public static void main(String[] args) throws InterruptedException {
        JoinRunnable joinRunnable = new JoinRunnable();

        Thread thread = new Thread(joinRunnable);
        thread.start();


        for (int i = 0; i < 100; i++) {
            if (i == 50) {
                thread.join();//The main thread is blocked until the vip thread is executed, and then the mian thread is executed
            }
            System.out.println("mian>>>>>>>>:" + i);
        }
    }

}

Sure enough, looking at the console output, when i=50 in mian, the thread is blocked, vip merges (cuts the queue) the thread and completes its own business.

mian>>>>>>>>:0
Join>>>>>:0
Join>>>>>:1
Join>>>>>:2
Join>>>>>:3
Join>>>>>:4
Join>>>>>:5
Join>>>>>:6
Join>>>>>:7
Join>>>>>:8
Join>>>>>:9
mian>>>>>>>>:1
Join>>>>>:10
Join>>>>>:11
Join>>>>>:12
Join>>>>>:13
Join>>>>>:14
mian>>>>>>>>:2
Join>>>>>:15
mian>>>>>>>>:3
Join>>>>>:16
mian>>>>>>>>:4
mian>>>>>>>>:5
mian>>>>>>>>:6
mian>>>>>>>>:7
mian>>>>>>>>:8
mian>>>>>>>>:9
mian>>>>>>>>:10
Join>>>>>:17
Join>>>>>:18
Join>>>>>:19
mian>>>>>>>>:11
mian>>>>>>>>:12
mian>>>>>>>>:13
mian>>>>>>>>:14
mian>>>>>>>>:15
mian>>>>>>>>:16
mian>>>>>>>>:17
mian>>>>>>>>:18
mian>>>>>>>>:19
mian>>>>>>>>:20
mian>>>>>>>>:21
mian>>>>>>>>:22
mian>>>>>>>>:23
mian>>>>>>>>:24
mian>>>>>>>>:25
mian>>>>>>>>:26
mian>>>>>>>>:27
mian>>>>>>>>:28
mian>>>>>>>>:29
mian>>>>>>>>:30
mian>>>>>>>>:31
mian>>>>>>>>:32
mian>>>>>>>>:33
mian>>>>>>>>:34
mian>>>>>>>>:35
mian>>>>>>>>:36
mian>>>>>>>>:37
mian>>>>>>>>:38
Join>>>>>:20
mian>>>>>>>>:39
Join>>>>>:21
mian>>>>>>>>:40
Join>>>>>:22
mian>>>>>>>>:41
Join>>>>>:23
Join>>>>>:24
Join>>>>>:25
Join>>>>>:26
Join>>>>>:27
Join>>>>>:28
Join>>>>>:29
Join>>>>>:30
Join>>>>>:31
Join>>>>>:32
Join>>>>>:33
Join>>>>>:34
Join>>>>>:35
Join>>>>>:36
Join>>>>>:37
mian>>>>>>>>:42
Join>>>>>:38
Join>>>>>:39
Join>>>>>:40
Join>>>>>:41
Join>>>>>:42
Join>>>>>:43
Join>>>>>:44
Join>>>>>:45
Join>>>>>:46
Join>>>>>:47
Join>>>>>:48
mian>>>>>>>>:43
Join>>>>>:49
Join>>>>>:50
Join>>>>>:51
Join>>>>>:52
Join>>>>>:53
Join>>>>>:54
Join>>>>>:55
Join>>>>>:56
Join>>>>>:57
mian>>>>>>>>:44
mian>>>>>>>>:45
mian>>>>>>>>:46
mian>>>>>>>>:47
mian>>>>>>>>:48
mian>>>>>>>>:49   *********************
Join>>>>>:58      *********************
Join>>>>>:....
Join>>>>>:998
Join>>>>>:999     *********************
mian>>>>>>>>:...
mian>>>>>>>>:98
mian>>>>>>>>:99

3.5 thread state observation

Thread.State Thread status. A thread can be in one of the following states
== New ==
Threads that have not been started are in this state
== RUNNABLE ==
stay java The state of execution in the virtual machine is in this state
== BLOCKED == 
Threads that are blocked waiting for a monitor lock are in this state
== WAITING ==
A thread that is waiting for another thread to perform a specific action is in this state
== TIMED WAITING ==
The thread that is waiting for another thread to perform the action for the specified waiting time is in this state
== TERMINATED ==
The exited thread is in this state.

A thread can be in a state at a given point in time, which does not reflect any operating system thread
 State of the virtual machine.

Thread status case Demo

package com.demo;

public class ThreadState implements Runnable {

    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("///");
    }


    public static void main(String[] args) throws InterruptedException {
        ThreadState threadState = new ThreadState();

        Thread thread = new Thread(threadState);

        //Observation status NEW
        Thread.State state = thread.getState();
        System.out.println(state);

        //RUN after thread startup
        thread.start();

        state = thread.getState();
        //Run phase
        System.out.println(state);

        //If the thread does not stop, it always outputs the state
        while (state != Thread.State.TERMINATED) {
            Thread.sleep(100);
            //Update status
            state = thread.getState();
            //
            System.out.println(state);
        }
    }
}

3.6 thread priority

1,Java A thread scheduler is provided to monitor all threads that enter the ready state after startup in the program,
The thread scheduler determines which thread should be scheduled to execute according to priority.
2,The priority of threads is expressed in numbers, ranging from 1~10
 2.1 Thread.MIN_PRIORITY=1
 2.2 Thread.MAX_PRIORITY=10
 2.3 Thread.NORM_PRIORITY=5
 Use the following methods to change or obtain priority
 ... getPriority().setPriority(int xxx)

Thread priority case Demo

package com.demo;

/**
 * thread priority 
 */
public class ThreadPriority implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "....>>>" + Thread.currentThread().getPriority());
    }


    public static void main(String[] args) {
        //Default priority of main thread
        System.out.println(Thread.currentThread().getName() + "....>>>" + Thread.currentThread().getPriority());
        ThreadPriority threadPriority = new ThreadPriority();

        Thread thread = new Thread(threadPriority);
        Thread thread2 = new Thread(threadPriority);
        Thread thread3 = new Thread(threadPriority);
        Thread thread4 = new Thread(threadPriority);
        Thread thread5 = new Thread(threadPriority);
        Thread thread6 = new Thread(threadPriority);

        //Set priority first and then start
        thread.start();
        thread2.setPriority(1);
        thread2.start();

        thread3.setPriority(4);
        thread3.start();
        
        //MAX_PRIORITY =10
        thread4.setPriority(Thread.MAX_PRIORITY);
        thread4.start();

        thread5.setPriority(-1);
        thread5.start();

        thread6.setPriority(11);
        thread6.start();
    }
}

The console reports an error. At this time, it shows that the low priority of threads only means that the probability of obtaining scheduling is low,
It is not that it will not be called if the priority is low. It depends on the CPU scheduling.

Thread-0....>>>5
Thread-1....>>>1
Thread-2....>>>4
Thread-3....>>>10
java.lang.IllegalArgumentException
	at java.lang.Thread.setPriority(Thread.java:1089)
	at com.demo.ThreadPriority.main(ThreadPriority.java:34)

3.7 daemon

1,Threads are divided into user threads and daemon threads
2,The virtual machine must ensure that the user thread has completed execution
3,The virtual machine does not have to wait for the daemon thread to finish executing,
Such as background recording operation log, monitoring memory, garbage collection, etc..

Daemon case Demo

package com.demo;

/**
 * Daemon thread
 */
public class ThreadDaemon {
    public static void main(String[] args) {
        God god = new God();
        Perople perople = new Perople();
        Thread thread = new Thread(god);
        //The default false indicates that the user thread is normal, and all threads are user threads
        thread.setDaemon(true);

        //God starts the daemon thread
        thread.start();


        Thread thread2 = new Thread(perople);
        //User thread start
        thread2.start();
    }


}

class God implements Runnable {
    @Override
    public void run() {
        while (true) {
            System.out.println("Oh, my God, bless the people");
        }

    }
}

class Perople implements Runnable {
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("People live happily every day");
        }
        System.out.println("====googbybe world ===");
    }
}

3.8 concurrency
Concurrency: the same object or resource is operated by multiple threads at the same time. Such as grabbing tickets, withdrawing money from two banks at the same time, sharing printers, or eating in the school restaurant.

	Causes of thread insecurity:
	**Because multiple threads of the same process share the same storage space, it brings convenience as well as convenience
	The problem of access conflict is solved. In order to ensure the correctness of data being accessed in the method, it is added when accessing
	Lock mechanism synchronized,When a thread obtains the exclusive lock of an object and monopolizes resources, other threads
	You must wait and release the lock after use. There are the following problems
	1,All threads that need this lock will hang.
	2,In multi-threaded competition, locking and releasing locks will lead to more context switching and scheduling delays,
	Cause performance problems.
	3,If a high priority thread waits for a low priority thread to release the lock(For example, a toilet,
	The high priority is just urinating, while the low priority is diarrhea, occupying the door latch resources,
	Only those with low priority can release the lock, and those with high priority can urinate. They may pee their pants) 
	This will cause priority and performance problems.

.
When dealing with multithreading, when multiple threads access the same object and some threads want to modify the object, we need thread synchronization. Thread synchronization is actually a waiting mechanism. Multiple threads that need to access the object at the same time enter the waiting pool of the object and form a queue (relative to the queue), waiting for the previous threads to be used up, The next thread is reused.

#Simulate the unsafe case of multi-threaded ticket purchase under concurrency

//Reproduce thread insecurity
public class TicketRunnable implements Runnable {
    private int ticket = 100;

    @Override
    public void run() {
        while (ticket > 0) {
            System.out.println(Thread.currentThread().getName() + ":Selling item" + ticket-- + ":ticket");
        }
    }

    public static void main(String[] args) {
        TicketRunnable ticketRunnable = new TicketRunnable();

        Thread thread = new Thread(ticketRunnable);
        Thread thread2 = new Thread(ticketRunnable);
        Thread thread3 = new Thread(ticketRunnable);

        thread.start();
        thread2.start();
        thread3.start();
    }
}

At this time, the three threads share the socket variable, and problems occur in parallel (the same ticket is sold, or even a negative ticket), such as console printing

Thread-1:Selling 100th:ticket
Thread-2:Selling 100th:ticket
Thread-0:Selling 100th:ticket
Thread-2:Selling 99th:ticket
Thread-1:Selling 99th:ticket
Thread-2:Selling 98th:ticket
Thread-0:Selling 99th:ticket
Thread-2:Selling 97th:ticket
Thread-1:Selling 98th:ticket
Thread-2:Selling 96th:ticket
Thread-0:Selling 98th:ticket
Thread-2:Selling 95th:ticket
Thread-1:Selling 97th:ticket
Thread-2:Selling 94th:ticket
Thread-0:Selling 97th:ticket
......................
Thread-2:Selling item-1:ticket

Thread unsafe collection cases

public class UnsafeCollection {
    public static void main(String[] args) {
    //Thread unsafe collection
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                list.add(Thread.currentThread().getName());
            }).start();
            System.out.println(list.size());
        }
    }
}

There are only 9996 console outputs.

9996

4 solve and issue thread insecurity.
4.1 synchronization method

1,Because we can pass private Keyword to ensure that data objects can only be accessed by methods,So we
 We only need to propose a set of mechanism for the method,This mechanism is synchronized keyword
 Syntax: public synchronized void method(int args){}
synchronized Method control pair"object"That is, each object corresponds to a lock,
each synchronized Methods must obtain the lock of the object calling the method in order to execute,Otherwise, the thread is blocked,
Once the method is executed,It monopolizes the lock and does not release the lock until the method returns,Only later blocked threads can
 Get this lock and continue.

Prerequisites for synchronization:
1, There must be two or more threads
2,Multiple threads must use the same lock.
Disadvantages of synchronization method:
If you declare a large method as synchronized It will affect efficiency (multiple threads need to judge locks, which consumes more resources).

The ticket selling problem can be solved at this time

ublic class Ticket implements Runnable {
    private static int ticket = 100;

    public void run() {
        buyTicket();

    }

    public synchronized void buyTicket() {
        while (ticket > 0) {
            try {
                //Analog delay 2s
                //Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + "Thread is selling" + ticket-- + "Ticket");


        }
    }

    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        
        Thread thread = new Thread(ticket);
        Thread thread2 = new Thread(ticket);
        Thread thread3 = new Thread(ticket);
        Thread thread4 = new Thread(ticket);

        thread.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

4.2 synchronization code block

Syntax:
synchnronized(Obj){}
1,Obj be called ==Synchronization monitor==Lock object
	.Objects are like locks. Threads that hold locks can synchronize.
	There is no thread holding the lock, even if it is obtained CPU Can't get in because there is no lock.
	Obj Can be any object, but is strongly recommended==shared resource==As a synchronization monitor.
	The so-called shared resources refer to the objects of addition, deletion and modification. It doesn't matter if you query.
	There is no need to specify a synchronization monitor in the synchronization method, because the synchronization monitor in the synchronization method is this,
	That is, the object itself, or.class
2,Synchronization monitor execution process
	2.1 The first thread accesses, locks the synchronization monitor, and executes business logic
	2.2 The second thread accesses and finds that the synchronization monitor is locked and cannot be accessed
	2.3 After the first thread is executed, unlock the synchronization monitor and release the lock resources
	2.4 The second thread accesses and finds that there is no lock. It grabs the lock resource and locks and accesses it
	2.5

Now you can use synchronized code blocks to solve the thread unsafe collection problem just now

public class UnsafeCollection {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
            	//Locked the resources shared by all threads
                synchronized (list) {
                    list.add(Thread.currentThread().getName());
                }
            }).start();

        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

Similarly, the synchronization code block can solve the unsafe problem of ticket selling

public class TicketRunnable implements Runnable {
    private int ticket = 100;
    Object object = new Object();

    @Override
    public void run() {

        while (true) {
            synchronized (object) {
                if (ticket > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + ":Selling item" + ticket-- + ":ticket");
                }
            }
        }

    }

    public static void main(String[] args) {


        TicketRunnable ticketRunnable = new TicketRunnable();

        Thread thread = new Thread(ticketRunnable);
        Thread thread2 = new Thread(ticketRunnable);
        Thread thread3 = new Thread(ticketRunnable);
        Thread thread4 = new Thread(ticketRunnable);
        Thread thread5 = new Thread(ticketRunnable);

        thread.start();
        thread2.start();
        thread3.start();
        thread4.start();
        thread5.start();
    }
}

5 deadlock
Multiple threads occupy some shared resources and wait for the resources occupied by other threads to run. As a result, two or more threads are waiting for each other to release resources and stop execution. For example, when a synchronous code block has locks on more than two objects, deadlock may occur.
5.1 deadlock avoidance method

Four necessary conditions for deadlock
1,Mutex condition: a resource can only be used by one process at a time.
2,Request and hold condition: when a process is blocked by requesting resources,Hold on to the resources you have obtained.
3,Conditions of non deprivation: the resources obtained by the process cannot be forcibly deprived before they are used up.
4,Circular waiting condition: a circular waiting resource relationship is formed between several processes.

All said that as long as we find a way to crack any one or more of these conditions, we can avoid deadlock.

6 Lock lock

1,from JDK5.0 start,Java Provides a more powerful thread synchronization mechanism--Define synchronization lock objects through display
 To achieve synchronization, synchronization lock is used Lock Objects act as.
2,java.util.concurrent.locks.Lock Interface is to control multiple threads to share resources
 Tools to access. Locks provide exclusive access to shared resources, with only one thread pair at a time Lock Object locking,
A thread should obtain a password before starting to access a shared resource Lock Object.
3,ReentrantLock Class implements Lock,It has and synchronized Same concurrency
 Memory semantics,In the control of thread safety,More commonly used is ReentrantLock,
You can display locking and releasing locks.
/**
 * lock Lock solves thread safety problems
 */
public class ReentrantLockTest implements Runnable {
    private ReentrantLock lock = new ReentrantLock();
    private int ticket = 1000;

    @Override
    public void run() {
        while (true) {
            try {
                lock.lock();
                if (ticket > 0) {
                    try {
                        //Thread.sleep(100);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // while (ticket > 0) {
                    System.out.println(Thread.currentThread().getName() + ": On sale" + ticket-- + "Ticket");
                    // }
                } else {
                    break;
                }
            } finally {
                lock.unlock();
            }
        }
    }

    public static void main(String[] args) {
        ReentrantLockTest reentrantLockTest = new ReentrantLockTest();

        Thread thread = new Thread(reentrantLockTest);
        Thread thread2 = new Thread(reentrantLockTest);
        Thread thread3 = new Thread(reentrantLockTest);
        Thread thread4 = new Thread(reentrantLockTest);

        thread.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }

7 difference between synchronized and Lock

1,Lock Show lock when locking(Manually open and close the lock),synchronized It's a hidden test,
The scope will be released automatically.
2,Lock Only code block locks,synchronized There are code block locks and method locks
3,use Lock Lock, Jvm It will take less time to schedule threads, with better performance and better scalability
(Provide more subclasses)
4,Limited use steps
Lock>Synchronous code block(Has entered the method body,Corresponding resources are allocated)>Synchronization method (outside the method body)

9 thread collaboration (producer consumer mode)
9.1 thread communication
Application scenario: producer and consumer issues
If only one product can be stored in the warehouse, the producer will put the produced products into the warehouse, and the consumer will take away the products in the warehouse for consumption.
If there is no product in the warehouse, the producer will put the product into the warehouse, otherwise stop production and wait until the product in the warehouse is taken away by the consumer.
If the product is placed in the warehouse, the consumer can take the product away for consumption, otherwise stop consumption and wait until the product is placed in the warehouse again.

9.2 thread communication - Analysis

This is a thread synchronization problem. Producers and consumers share the same resource,And between producers and consumers
 Interdependent and conditional.
1,For producers, consumers should be informed to wait before producing products, and after producers produce products,
It is necessary to inform consumers of consumption immediately.
2,For consumers, after consumers, they should inform producers that they have finished consumption and need to produce new products
 For consumption.
3,In the producer consumer problem, only synchronized It's not enough,
	3.1 synchronized Prevents concurrent updates to the same shared resource,Synchronization is realized.
	3.2 synchronized It cannot be used to realize message passing between different threads(signal communication)

9.3 = = thread communication method==

java Several methods are provided to solve the communication problem between threads
1,wait() :  Indicates that the thread waits until notified by other threads, and sleep Different, the lock will be released
2,wait(long timeout): Specifies the number of milliseconds to wait
3,notify():           Wake up a waiting thread
3,notifyAll(): Wake up all calls on the same object wait()Method, with high priority
				Thread priority scheduling
 They are all parents Object All methods can only be used in synchronization methods or synchronization code blocks, otherwise
 Will throw IIIegalMonitorStateException

9.4 thread communication mode - pipe method

Concurrent collaboration model "producer"/"Consumer" -->Pipe program method
 Producer: the module responsible for production data (may be method, object, thread, process)
consumer:Module responsible for processing data
 Buffer: consumers cannot use the producer's data directly,There's a buffer between them,
The producer puts the produced data into the buffer, and the consumer takes out the data from the buffer


Producer / consumer model - > case of pipe process method
10 thread pool

Why use thread pools?
reason:Frequently create and destroy resources that are heavily used, such as threads in concurrency,It has a great impact on performance.
Solution ideas:Create multiple threads in advance,Put into thread pool,Get it directly when you use it, and put it back into the pool after use.
sure
 Avoid frequent creation, destruction and reuse. Similar to transportation in life.
advantage:
	1,Improve response speed(Reduced time to create new threads)
	2,Reduce resource consumption(Reuse threads in thread pool,You don't need to create it every time)
	3,Easy thread management
		.corePoolSize:Size of core pool
		.maximumPoolSize:Maximum number of threads
		.keepAliveTime:How long does the thread last when there is no task

10.1 use of wire path pool
JDK5. From 0 onwards, thread pool related API s are provided: ExcutorService and Executors
ExcutorService: real thread pool interface, subclass ThreadPoolExecutor

	void execute(Runnable command):Perform tasks/Command, no return value,
	Generally used to perform Runnable
	<T>Futrue<T>submit(Callable<T>task):Perform tasks,There is a return value,Generally used
	implement Callable
	void shutdown():Close connection pool
	Executors:Factory class of tool class and thread class,Used to create and return different types of thread pools

10.1 case of linear process pool

public class ExecutorsTest {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.execute(new ThreadTest());
        executorService.execute(new ThreadTest());
        executorService.execute(new ThreadTest());
        executorService.execute(new ThreadTest());
        executorService.shutdown();
    }

}

class ThreadTest implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

Topics: Java Multithreading