@[toc]

1. Understand threads and processes

Since concurrency certainly involves multithreading, it will be helpful to understand the origins of processes and threads before we dive into the topic of concurrent programming.

Process and thread comparison this knowledge point because too basic, because too basic, so we should thoroughly it! We must master what is thread and process, master the relationship between thread and process, difference and advantages and disadvantages!

1.1. What is process?

First let’s look at the concept of process:

Process: refers to an application running in memory. Each process has an independent memory space. An application can run multiple processes at the same time. Process is also a procedure of execution process, is the basic unit of the system running procedures; System running a program is a process from creation, operation to extinction process.

After watching it, doesn’t it feel abstract? Very meng bi? Meng BI is right, explain you and my IQ as high…. Just kidding

Might as well first suppress the above concept, relax your brain, double click open LOL, seconds choose De Ma play wild, lost directly quit the game and maintain a smile, and then sit calmly to see the blog written by Yichun….

This time you are not only happy to masturbate a game, but also experience the process of masturbation… The process is created when you double-click LOL to open it. As we all know, our computers have software like: LOL, WeChat, Google and so on are all stored in our hard disk, hard disk data can be said to be permanent storage (ORM), when we double click LOL LOL program into the memory, all programs must enter to perform in the memory, the memory belongs to temporary memory (RAM), and into the memory of the program can be called is a process, When you exit the LOL application, the LOL application will exit memory and the process will be destroyed! So it’s an understatement to say that you’ve made progress.

What? Word is too much, see not clear enough, not as good as see the picture…. Er…

1.2. What is a thread?

Again, let’s start with the idea of threads

A thread is a unit of execution in a process that is responsible for the execution of programs in the current process. There is at least one thread in a process, that is to say, a process can have multiple threads, and the process application of multiple threads is called multithreaded program

The concept of threads is a little easier to understand, but it’s not enough to get a deeper understanding of the overview of the above paragraph!

This does not play LOL in the process, true card of a batch, sure enough to spend a high price of 998 bought 6 hands of Dell notebook play LOL true like love. This time had to double-click on the computer security housekeeper for antivirus, as expected 2500 days did not carry out virus check, my day… In fact, I believe that a lot of people are using a computer, such as cell phones steward housekeeper or security software, we are all very clear after we open virus killing typically scan killing a few minutes, we can make it this background, we won’t wait but open another function of rubbish, this time we won’t wait for it to start computer acceleration. Wait until these operations are completed after the decisive exit computer housekeeper, continue LOL, as expected the high price of 998 bought 6 hands of Dell notebook again how to kill virus play LOL or the same card….

In fact, it is clear that threads must involve CPU related concepts. The above text is described by the picture, which is roughly:

1.3. What is multithreading?

From the previous section, we also mentioned multithreading, so it shouldn’t be difficult to understand.

Multithreading is multiple threads running at the same time or alternately.

Single-core CPU: Runs alternately. Multi-core CPU: run simultaneously.

In fact, multi-threaded programs can not improve the speed of the program, but can improve the efficiency of the program, so that the CPU usage is higher.

1.4. What is thread scheduling priority?

The idea of thread scheduling priorities reminds me of what most of us do when we send resumes. The higher your degree or experience, the higher your priority, the more likely the interviewer will call you for an interview, but not necessarily more likely, if the threads are of the same priority, then one will be chosen at random (thread randomness)! Threads can be prioritized on each of our computers, but kids who don’t have a priority in life are left to their own devices. ~

Thread priority has inheritance properties. For example, thread A starts thread B, and thread B has the same priority as thread A.

Thread priority is random, which means that threads with higher priority do not always finish first, but are more likely to be executed.

We will use the getPriority() method to get the priority of a thread in future multithreading trips.

1.5. Why is it recommended to use multi-threading rather than multi-processing?

A thread is similar to a process, but a thread is a smaller unit of execution than a process, the smallest unit of program execution. A process can produce multiple threads during its execution. Unlike a process, many threads of the same kind share the same memory space and a group of system resources, so the system is much less burden than a process when producing a thread or switching between threads. It is also because of this, threads are also called lightweight processes. Concurrent threads are the smallest unit of program execution. Design concurrent programs using multiple threads rather than multiple processes because switching and scheduling costs between threads are much less than processes.

But using multithreading, multithreading will change the way the program runs from serial to concurrent, efficiency will be greatly improved.

Understand parallelism and concurrency

Among bloggers, concurrency and parallelism are two very confusing concepts. In order to avoid confusing everyone, so I choose to make a long story short!

  1. concurrentA:Period of timeInternal simultaneous (not simultaneous).
  2. parallel: the samemomentTake place (really take place simultaneously)

They can represent two or more tasks executed together, but the emphasis is somewhat different.

In the meantime, let’s take a look back at the CPU mentioned above and re-understand the difference between concurrency and parallelism. I’m a genius! ~

Single-core CPU: run alternately [concurrent] Multi-core CPU: run simultaneously [parallel]

And send a person’s feeling is running at the same time, that is because the time of alternating running time is very short!

3. Special single thread: Main thread

The Main thread is called the Main thread. It is a special single thread.

Define a Demo class Person for testing

package demo;

public class Person {
   public String name;

   public Person(String name){
       this.name=name;
   }

   public void run(){
       int i=1;
       while (i<5){
           System.out.println(name+i);
           i++;
       }
   }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name; }}Copy the code

Write the Main method

package demo;

public class MainThreadDemo {
    public static void main(String[] args) {
        Person per=new Person("Chang Wei");
        per.run();

        Person Per2=new Person("Live"); Per2.run(); }}Copy the code

The results are pretty obvious, so I’m not relying on your results but just analyzing the main thread first.

Operation result: changwei1Chang Wei2Chang Wei3Chang Wei4rifle1rifle2rifle3rifle4
Copy the code

3.1. Analyze the principle of main thread

3.2. Limitations of single threads

Single threading is not only inefficient, but also has great limitations. Its only advantage is safety. So being safe for girls is actually an advantage, poof ha ha ha…

How do you address the inefficiency and limitations of single threading? In fact, as long as a single line of code, or the above single thread Main thread for example:

package demo;

public class MainThreadDemo {
    public static void main(String[] args) {
        Person per=new Person("Chang Wei");
        per.run();
        int a=6/0;  //===================== pay special attention to this line of code
        Person Per2=new Person("Live"); Per2.run(); }}Copy the code

Just think about the results…

If you’re dead, try it. If you’re dead, catch it.

Anyway, why is it inefficient? It’s a small amount of data. If it’s 100 million pieces of data, a single thread would print them one by one. How do we know the limitations? As can be seen from the above results, the following code is no longer executed because of a single line of code. It’s already obvious.

4. Four ways to create multiple threads

There are four ways to create multithreading, but the remaining two are ignored for now, considering whether it is an introductory article or mainly two ways to write an introductory article. Two approaches that are ignored are implementing the Callable interface to create Thread threads through the FutureTask wrapper, and implementing threads that return results using ExecutorService, Callable, and Future. Now may be for the entry of children’s shoes is not received, later to understand it is not too late!

4.1. Inherit the Thread class

Java uses the java.lang.Thread class to represent threads, and all Thread objects must be instances of the Thread class or its subclasses. The purpose of each thread is to perform a certain task, which is essentially to execute a stream of code that is executed sequentially. Java uses the thread body to represent this program flow.

The steps to create and start multithreading in Java by inheriting the Thread class are as follows:

  1. defineThreadClass, and override the class’s subclassrun()Method, whichrun()The method body of the method represents the task that the thread needs to complete, so therun()Methods are called thread bodies.
  2. createThreadAn instance of a subclass that creates a thread object
  3. Of the call thread objectstart()Method to start the thread

The code is as follows:

The test class:

public class Demo01 {
	public static void main(String[] args) {
		// Create a custom thread object
		MyThread mt = new MyThread("New thread!");
		// Start a new thread
		mt.start();
		// Execute the for loop in the main method
		for (int i = 0; i < 10; i++) {
			System.out.println("Main thread!"+i); }}}Copy the code

Custom thread class:

public class MyThread extends Thread {
	// Define a constructor that specifies the thread name
	public MyThread(String name) {
		// Call the String constructor of the parent class, specifying the name of the thread
		super(name);
	}
	/** * Override the run method to complete the thread's logic */
	@Override
	public void run(a) {
		for (int i = 0; i < 10; i++) {
			System.out.println(getName()+": Executing!"+i); }}}Copy the code

The Thread class is essentially an instance that implements the Runnable interface and represents an instance of a Thread. The only way to start a Thread is through the start() instance method of the Thread class. The start() method is a native method that starts a new thread and executes the run() method. It is easy to implement multithreading in this way. By extending Thread directly from your own class and overwriting the run() method, you can start a new Thread and execute your own run() method.

4.2. Implement Runnable interface

If your own class already inherits another class, you cannot inherit threads directly. In this case, you can implement a Runnable interface to create threads.

Direct lifting:

A custom class implements the Runnable interface, overwrites the run() method in the interface, and adds code methods to the run method to execute.

public class RunableDemo implements Runnable{

    @Override
    public void run() {
        int a = 1;
        while (a<20){
            System.out.println(Thread.currentThread().getName()+ a);// thread.currentthread ().getname () is the name of the currentThreada++; }}}Copy the code

Write the Main method

To start the custom RunableDemo class, first instantiate a Thread and pass in the RunableDemo instance:

public class MainThreadDemo {

    public static void main(String[] args) {
        RunableDemo runn=new RunableDemo();
        
        // Instantiate a Thread and pass in your own RunableDemo instance
        Thread thread=new Thread(runn);
        thread.start();

        int a = 1;
        while (a<20) {// thread.currentthread ().getname () is the name of the currentThreadSystem.out.println(Thread.currentThread().getName()+ a); a++; }}}Copy the code

Running results:

main1
main2
main3
Thread- 01
Thread.
Thread- 03
Thread- 04
Thread- 05
Thread- 06.Copy the code

In fact, if you run the methods more than once, the order of results will be different each time you run them. This is mainly due to the fact that multiple threads are trying to grab the CPU resources, and whoever grabs the CPU resources executes, whereas the Main and Thread threads are always fighting for the resources.

In fact, when a Thread is passed a Runnable target, its run() method calls target.run(). See JDK source code:

public voidrun() { &emsp; &emsp;if(target ! =null) { &emsp; &emsp; target.run(); &emsp; &emsp; }}Copy the code

4.3. Differences between the two entry-level creation threads

Inheriting the Thread class:

(1) advantages: easy to write, if you need to access the currentThread, no need to use thread.currentthread () method, directly use this, can obtain the currentThread. (2) Disadvantages: Since Thread classes already inherit from Thread classes, they cannot inherit from other parent classes.

Implement the Runnable interface:

(1) Advantages: Thread classes only implement the Runable interface, but can also inherit from other classes. In this way, multiple threads can share the same target object, so it is very suitable for multiple threads to deal with the same resource, which can separate THE CPU code and data, form a clear model, better reflect the idea of object-oriented. (2) disadvantages: programming is a bit complicated, and thread.currentthread () must be used if you need to access the currentThread.

Summary: If a class inherits Thread, it is not suitable for resource sharing. However, if the Runable interface is implemented, it is easy to implement resource sharing.

Implementing the Runnable interface has advantages over inheriting the Thread class:

1. It is suitable for multiple threads of the same code to process the same resource.

2. You can avoid the restriction of single inheritance in Java.

3. Increase code robustness and decouple. Code can be shared by multiple threads, and code and data are independent.

4. A Thread pool can only be used for threads that implement Runnable or Callable classes, not for classes that inherit threads.

So, if you choose either way, try to implement the Runnable interface!

In fact, if you look at thread pools later, you will find that the above two methods of thread creation are rarely used, and are generally used more in thread pools. In addition, “Alibaba Java Development Manual” also emphasizes that “thread resources must be provided through the thread pool, and it is not allowed to display the creation of threads in the application” in the section 6 of Concurrent processing in Chapter 1. However, beginner shoe bloggers strongly recommend taking one step at a time!

Create threads using anonymous inner classes

Talking about anonymous inner class, may be a lot of small white is relatively strange, after all, the development of the use of relatively little, but it is also a very important knowledge! In the meantime I’ll post about anonymous inner classes programmer do you really understand anonymous inner classes? If white boy shoes can read this code, you really don’t need to read that article, you are a fucking genius!

package AnonymousInner;

public class NiMingInnerClassThread {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i<5; i++){ System.out.println("Child Bear:"+i); }}};new Thread(r).start();
        for (int i = 0; i < 5 ; i++){
            System.out.println("Silly roe deer :"+i); }}}Copy the code

Small white children shoes still leng to do what ah hurriedly repair…

6. Thread safety

Main thread safety issues is a question of sharing resource competition, which is under the condition of multiple threads, one or more threads preempted the same resource at the same time cause some unnecessary problems, the most typical example is the train four window ticket problem, there is no longer ticketing example, already rotten street, here is simple to realize a thread safety code…

For example, to implement the Runnable interface, the main implementation process is: instantiate three threads, pass the same RunableDemo instance as a parameter, and finally start three threads with the same parameter, the code is as follows:

public class RunableDemo implements Runnable{
    public int a = 100;// Threads share data
    
    @Override
    public void run() {
        while (a>0){
            System.out.println("Thread"+Thread.currentThread().getName()+"Execute to"+ a); a--; }}}Copy the code
public class MainThreadDemo {

    public static void main(String[] args) {
        RunableDemo runn=new RunableDemo();
        
        Thread thread1=new Thread(runn);
        Thread thread2=new Thread(runn);
        Thread thread3=newThread(runn); thread1.start(); thread2.start(); thread3.start(); }}Copy the code

Running results:

Thread0= =100
Thread0= =99
Thread- 1= =100
Thread- 1= =97
Thread- 1= =96
Thread- 1= =95
Thread2 -= =98.Copy the code

Thread 0, Thread 1, Thread 2, Thread 0, Thread 0, Thread 0, Thread 0, Thread 0, Thread 0 How to solve this situation? This is where thread synchronization comes in!

7, solve the thread safety problem: thread synchronization

In fact, there are three solutions to the thread-safety problem:

1. Synchronization code block 2. Synchronization method 3

7.1 Synchronized code block

The first method: synchronize code blocks

Format:

Synchronized {code that may cause thread-safety problems (code that accesses shared data)}Copy the code

Use synchronized code block special attention: 1, through the code block lock object, can be any object 2, must ensure that the lock object used by multiple threads must be the same 3, the lock object is to synchronize the code fast lock, only allow one thread in the synchronized code block execution

Using the thread safety issue above as an example, use a synchronized code block as an example:

public class RunableDemo implements Runnable{
    public int a = 100;// Threads share data

    Object object=new Object(a);// Prepare a lock object in advance

    @Override
    public void run() {
        synchronized (object){  // Use synchronized code blocks
        while (a>0){
            System.out.println("Thread"+Thread.currentThread().getName()+"Execute to"+ a); a--; }}}}Copy the code

The Main method has not changed any, run the result is absolutely no problem, the data is correct, there is no repetition of this one, you can try it yourself!

How blocks of synchronized code work:

Use a lock object, called sync lock, object lock, also called synchronous monitor, when open multiple threads, multiple threads started to grab the executive power of CPU, such as t0 the first thread to execute, now will start to implement the run method, fast synchronization code, first check whether there is a lock object, found, is to get the lock object, Executes the code in the synchronized code block. Later, when CUP switches threads, such as T1 gets executed, it also starts to execute the run method. However, when it checks whether there is any lock object in the synchronized code block, T1 will be blocked and wait for t0 to finish executing the synchronized code block and release the lock object. Only then can T1 obtain the lock object and enter the synchronized code block for execution. In the synchronization thread, the lock will not be released until the execution is completed, so that the thread can achieve mutually exclusive access to the critical area and ensure the security of shared data. Disadvantages: Frequent access to release lock objects, reduce program efficiency

7.2. Synchronization method

Use steps:

Extract code that accesses shared data and place it in a method. 2. Add the synchronized modifier to that method

Format:

Synchronized return value type method name (argument list) {method body... }Copy the code

Code examples:

public class RunableDemo implements Runnable{
    public int a = 100;// Threads share data

    @Override
    public void run() {
        while (true){
            sell(); // Call the sell method below}}// The code that accesses the shared data is extracted and placed in a method sell
    public synchronized void sell(){
        while (a>0){
            System.out.println("Thread"+Thread.currentThread().getName()+"Execute to"+ a); a--; }}}Copy the code

The same is true for synchronized methods, but the locking object is the Runable implementation class object, which is this, and whoever calls the method is the same.

Static sync (); static sync (); static sync (); static sync ();

public class RunableDemo implements Runnable{
    public static int a = 100;// Threads share data =====

    @Override
    public void run() {
        while (true){
            sell();
        }
    }

    public static synchronized void sell(){  // Notice the addition of the static keyword
        while (a>0){
            System.out.println("Thread"+Thread.currentThread().getName()+"Execute to"+ a); a--; }}}Copy the code

Static sync = static; static sync = static; static sync = static; static sync = static; static sync = static; Understand the static keyword in depth

Of course, the static synchronization method can understand!

7.3, the Lock Lock

Lock interface in Java. Util. Concurrent. The locks, Lock it is following a JDK1.5, Lock the interface methods:

Void lock(): obtains the lock

 

Void unlock(): Releases the lock

The Lock interface of a Java implementation class. Util. Concurrent. The locks. Already implements Lock interface

Create a ReentrantLock object in a member variable of the Runable implementation class. The object calls the lock method to acquire the lock before code that may cause thread-safety problems. The object calls the UNLOCK method to release the lock after code that may cause thread-safety problems

Code examples:

import java.util.concurrent.locks.ReentrantLock;

public class RunableDemo implements Runnable{
    public static int a = 100;// Threads share data

    // create a ReentrantLock object ============ in the member variable of the Runable implementation class
    ReentrantLock reentrantLock = new ReentrantLock();

    @Override
    public void run() {
        // 2. This object calls the lock method to obtain the lock ======= before code that may cause thread-safety problems
        reentrantLock.lock();
        while (a>0){
            System.out.println("Thread"+Thread.currentThread().getName()+"Execute to"+ a);
            a--;
        }
        // 3. This object calls unlock to obtain the lock ====== after code that may cause thread-safety problemsreentrantLock.unlock(); }}Copy the code

Of course, it is safer to write in thread-safe code try… Catchy, and finally add reentrantLock.unlock(); This is the best way!

7.4. Summary of the three methods

The first type of synchronized code block: it can be any object and must ensure that multiple threads use the same lock object

 

The second synchronized method: the lock object is this, and whoever calls the lock object is the same

 

Synchronized static synchronization method: The lock object is its class object, which can be obtained using this.getClass() or denoted by the current class name. Class. 【 Understand 】

 

The third Look lock method provides more methods than synchronized. This method creates a ReentrantLock object in a member variable of the Runable implementation class, and uses the object to call the Lock method to obtain the lock and unlock method to release the lock!

8, common thread methods

8.1, the Thread class

Thread() : Construct a new Thread.

Thread(Runnable target) : Constructs a new Thread that uses the run method of the specified target.

ThreadGroup group (Runnable target) : Used to construct a new Thread in the specified Thread group

The thread uses the run method for the specified target.

CurrentThread () : Gets an object reference to the current running thread.

Interrupt () : Sets the current thread to the interrupted state.

Sleep (Long millis) : Puts the currently running thread to sleep for at least a specified number of milliseconds.

Join () : Wait for this thread to terminate, that is, calling other.join() in a thread will wait for the other thread to terminate before continuing this thread.

Yield () : The currently executing thread cedes CPU usage from the run state to the ready state for other ready threads to execute.

8.2, the Object class

Wait () : To block the current thread until another thread calls notify() or notifyAll() on this object.

Notify () : Wakes up a single thread waiting on this object monitor (lock object).

NotifyAll () : Wakes up all threads waiting on this object monitor (lock object).

Note: Wait (), notify(), and notifyAll() all rely on synchronous locks, which are held by objects and have only one per Object. Therefore, these methods are defined in the Object class, not in the Thread class.

8.3. Compare yield(), sleep(), and wait()

Wait () : Moves a thread from a running state to a waiting blocked state and releases any synchronization locks it holds.

Yield () : Puts a thread from the run state into the ready state without releasing the synchronization lock it holds.

Sleep () : Blocks the thread from running without releasing the synchronization lock it holds.

Thread state

If you want to take a closer look, you can: 6 states and transitions for Java threads

10. Thread pools

In Java, as long as the pool is mentioned, it is basically a routine, such as database connection pool, JDBC connection pool, etc., the idea is basically: a container containing multiple resources to be used, the resources can be used repeatedly, eliminating the operation of creating thread objects frequently, and there is no need to repeatedly create resources and consume too many resources.

10.1 overview of thread pools

In fact, a thread pool is a container containing multiple threads, which can be used repeatedly, eliminating the need to repeatedly create thread objects and consume too many resources.

There are three benefits to using thread pools properly:

  1. Reduce resource consumption. The number of threads created and destroyed is reduced, and each worker thread can be reused to perform multiple tasks.
  2. Improve response speed. When a task arrives, it can be executed immediately without waiting for the thread to be created.
  3. Improve thread manageability. You can adjust the number of working threads in the thread pool according to the system’s capacity to prevent excessive memory consumption, and the server is exhausted (each thread needs about 1MB of memory, the more threads open, the more memory consumption, and finally crash).

10.2 use of thread pools

Java thread pool inside the top interface is Java. The util. Concurrent. The Executor, but strictly Executor is not a thread pool, but only one thread of execution tools. The real thread pool interface is Java. Util. Concurrent. The ExecutorService.

To configure a thread pool is relatively complex, especially for the principle of the thread pool is not very clear, very likely configuration of thread pool is not better, so in Java. Util. Concurrent. The Executors thread factory class provides static factory, generate some common thread pool. Officials recommend using the Executors project class to create thread pool objects.

Create a thread pool by following the Executors class:

  • public static ExecutorService newFixedThreadPool(int nThreads): Returns a thread pool object. (create a pool of bounded threads, that is, the number of threads in the pool can specify the maximum number)

A thread pool object can be used as an ExecutorService object.

  • public Future<? > submit(Runnable task): Gets a thread object in the thread pool and executes

Future interface: Used to record the results of thread tasks after completion. Thread pool creation and use.

Steps for using thread objects in a thread pool:

  1. Create a thread pool object.
  2. Create a Runnable interface subclass object. (task)
  3. Submit the Runnable interface subclass object. (take task)
  4. Close the thread pool (this step is generally not done).

Runnable implementation class code:

public class MyRunnable implements Runnable {
    @Override
    public void run(a) {
        System.out.println("I want a swimming coach.");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Here comes the coach:" + Thread.currentThread().getName());
        System.out.println("Taught me how to swim, and after that, the instructor went back to the pool."); }}Copy the code

Thread pool test class:

public class ThreadPoolDemo {
    public static void main(String[] args) {
        // Create a thread pool object
        ExecutorService service = Executors.newFixedThreadPool(2);// Contains two thread objects
        // Create Runnable instance objects
        MyRunnable r = new MyRunnable();

        // How to create your own thread object
        // Thread t = new Thread(r);
        // t.start(); Call run() in MyRunnable

        // Get the thread object from the thread pool and call run() in MyRunnable
        service.submit(r);
        // Get a thread object and call run() in MyRunnable
        service.submit(r);
        service.submit(r);
        // Note: The program does not terminate after the submit method call, because the thread pool controls the closing of the thread.
        // Return the used thread to the thread pool
        // Close the thread pool
        //service.shutdown();}}Copy the code

This is just a simple use of thread pools, just getting started! The road is blocked and long, the road is still very long….

Here, this article entry temporarily concluded, later have time to try to find time to update….

If this article is helpful to you, even a little bit, please give a thumbs up. Thank you

Welcome to pay attention to my public number, discuss technology together, yearning for technology, the pursuit of technology… Said come is a friend oh…