It's multithreaded, so beginners can understand it

What is thread

  • When it comes to threads, we should first understand what a process is. You should be familiar with this picture.


The programs we see running separately are independent processes, and the processes are independent of each other. The 360 browser and Baidu cloud disk in the above figure are all independent processes.

  • So what are threads?

Thread is the smallest unit that the operating system can schedule operations. It is included in the process and is the actual operating unit of the process. A thread refers to a single sequential control flow in a process. Multiple threads can be concurrent in a process. Each thread performs different tasks in parallel. In Unix System V and SunOS, it is also called lightweight processes, but lightweight processes refer to kernel thread s more than user thread s.

The above definition is to introduce Baidu Encyclopedia. It seems to be full of literature. It's not easy to understand what they are talking about. Let's talk about people. Foxconn, the largest factory, we all know whether there are many production workshops and many assembly lines in one workshop. We can think of a process as a workshop, so threads are a pipeline in the workshop. The working process of a workshop is a process, and the working process of a pipeline is a thread. Process is the smallest unit of operating system resource allocation (workshop 8 of manufacturing section is responsible for producing 100w mobile phone shells), and thread is the smallest unit of cpu scheduling (each production line in workshop 8 is responsible for the specific task of generating mobile phone shells).

Why use multithreading

  • Faster response time

This is easy to understand. For example, in a workshop, one assembly line can produce 1w mobile phone cases in two shifts a day (working 24 hours). If you want to produce 100w mobile phone cases, if there is only one production line in one workshop, does it take 100 days. 100 days later, the case is out of date. If there are 50 parallel production lines in a workshop, is it possible to produce 100w mobile phone shell in 2 days.

  • More processor cores

Thread is the basic unit of most operating system scheduling. A program runs as a process, which can create multiple threads, while a thread can only run on one processor core at a time.

  • Better programming model
    Java provides a good way for multithreading programming. A sophisticated and consistent programming model enables developers to focus more on problem solving, that is, to build a suitable model for the problems they encounter, rather than trying to think about how to multithread them. Once the developer has established the model, a little modification can always easily map to the multithreaded programming model provided by Java.

How to create multithreads

  • First, create a Thread class by inheriting the Thread class
package com.workit.demo.thread;

public class ExtendsThread extends Thread {
    public static void main(String[] args) {
        for(int i = 0;i<10;i++){
            //Create and start threads
            new ExtendsThread().start();
        }
    }
    @Override
    public void run() {
        System.out.println(this.getName());
    }
}
  • Second, create a thread class by implementing the Runnable interface
package com.workit.demo.thread;

public class RunnableThread implements Runnable {
    public static void main(String[] args) {
        for(int i = 0;i<10;i++){
            //Create and start threads
            new Thread(new RunnableThread()).start();
        }
    }

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

There are other online and multi version implementations, for example, created through the Callable and Future interfaces, but these are nothing more than encapsulation of the above, which I don't think can be used as an implementation method. oracle official website also said that there are only two ways to create threads.

Interested students can go and have a look Two ways to create threads

How to ensure thread safety

For example, whether materials are needed for the production of mobile phone shell in the workshop, whether materials are collected in the warehouse, if each assembly line sends A person to collect them. Everyone swarmed to scramble for materials. Assembly line A receives the materials that belong to assembly line B, and assembly line C dries the materials that belong to assembly line D. In the end, some assembly lines have no materials. What should we do to solve this problem? The warehouse has set A rule that only one person can pick up the materials at A time, and everyone can queue up to pick up the materials. So the order is much better, but suddenly one day A fat man saw that someone had finished taking it, and he directly inserted it to the opposite side to take it (the legendary unfair lock). The people in the back dare not say that baby's heart is bitter.

Later, the warehouse has specified rules, which must be followed in the order of first come, last come. If there is a queue break, a fine of 100 yuan will be imposed. In this way, we all follow the order of first come, then come. When picking up materials, we should first see if there are any people queuing up. If there are no people queuing up, we don't need to go to the queue to pick up materials directly. If there are people queuing up, we will consciously go to the end of the queue. (legendary fair lock)
Ah, I've said a lot of rubbish. Let's get back to the point. Thread safety is embodied in three aspects

  • Atomicity:

Mutual exclusive access is provided, and only one thread can operate on it at the same time.

Assembly line workers can only get materials from one person at the same time.

  • Visibility:

One thread's modification to main memory can be observed by other threads in time.

The number of materials left in the warehouse after the former assembly line worker received 10w is visible to the later workers.

Order:

The execution order of the program is in accordance with the code order. In the single thread environment, the execution of the program is orderly. However, in the multithreaded environment, in order to optimize the performance of JMM, the compiler and processor will rearrange the instructions, and the execution of the program will become disordered.

  • For example, when picking up materials in the warehouse, there are three steps. The first step is to confirm the information to verify which workshop and production line you are in, the second step is to fill in the material picking list, and the third step is to pick up materials at the material place. Sometimes these steps can be interchanged if the warehouse is to improve work efficiency. It can be in the order of 2 - > 1 - > 3. It can also be in the order of 3 - > 2 - > 1.

The following code to demonstrate how to get the right material. 100 assembly lines, each assembly line receives 1000 materials, and the final material should be 0

  • synchronized keyword
package com.workit.demo.thread;

import jdk.nashorn.internal.runtime.options.LoggingOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;

import java.util.concurrent.CountDownLatch;


public class RunnableThread implements Runnable {
    private final static Logger LOG = LoggerFactory.getLogger(RunnableThread.class);
   static CountDownLatch countDownLatch = new CountDownLatch(100);
    public static void main(String[] args) throws InterruptedException {
        RunnableThread runnableThread = new RunnableThread();
        for(int i = 0;i<100;i++){
            //Create and start threads
            Thread thread = new Thread(runnableThread);
            // Assembly line
            thread.setName("Assembly line:"+i);
            thread.start();
        }
        countDownLatch.await();
        System.out.println("Warehouse surplus material:"+runnableThread.count);

    }

    // Total materials volatile   
    private  int  count =100000;

    @Override
    public  void run() {
       int  remainCount =get();
        countDownLatch.countDown();
       LOG.info(Thread.currentThread().getName()+":After receiving the materials, the warehouse still leaves the materials:"+remainCount);
    }

    public  synchronized    int  get(){
        for(int i =0;i<1000;i++){
            count--;
        }
        return count;
    }
}

Why can synchronized ensure thread safety?
Synchronized uses Monitor (monitoring lock) to ensure that resources block mutually exclusive access in a multithreaded environment. It is a JVM level lock. By the way, it's still an unfair lock. This is not a detailed introduction to the follow-up after turning to write an article to introduce it.

  • Use lock lock to ensure thread safety.

So is Lock java.util.concurrent An interface under the package defines a series of Lock operation methods. The Lock interface mainly includes ReentrantLock. It can be a fair Lock or an unfair Lock. Set by constructor.

package com.workit.demo.thread;

import jdk.nashorn.internal.runtime.options.LoggingOption;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


public class RunnableThread implements Runnable {
    private final static Logger LOG = LoggerFactory.getLogger(RunnableThread.class);
    static CountDownLatch countDownLatch = new CountDownLatch(100);
    static Lock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        RunnableThread runnableThread = new RunnableThread();
        for (int i = 0; i < 100; i++) {
            //Create and start threads
            Thread thread = new Thread(runnableThread);
            // Assembly line
            thread.setName("Assembly line:" + i);
            thread.start();
        }
        countDownLatch.await();
        System.out.println("Warehouse surplus material:" + runnableThread.count);

    }

    // Total materials volatile 
    private int count = 100000;

    @Override
    public void run() {
        int remainCount = getByLock();
        countDownLatch.countDown();
        LOG.info(Thread.currentThread().getName() + ":After receiving the materials, the warehouse still leaves the materials:" + remainCount);
    }


    public int getByLock() {
        lock.lock();
        try {
            for (int i = 0; i < 1000; i++) {
                count--;
            }
            return count;
        } finally {
            lock.unlock();
        }
    }
}

summary

  • What are the causes of thread safety problems?

In the multithreaded concurrent environment, when multiple threads access the same shared memory resource together, one thread writes to the resource halfway (the write has started, but not yet finished), and other threads read or write to half of the resources written, resulting in data errors of the resource.

  • How to avoid thread safety problems?

Ensure that the shared resources can only be operated by one thread at the same time (atomicity, orderliness).
Refresh the results of thread operation in time to ensure that other threads can get the latest modified data (visibility) immediately.

end

  • Due to their lack of talent and learning, there will inevitably be mistakes. If you find the wrong place, please leave a message for me to point out, and I will correct it.
  • If you think the article is not bad, your forwarding, sharing, appreciation, likes and comments are my biggest encouragement.
  • Thank you for reading, welcome and thank you for your attention.


reference resources
https://zhuanlan.zhihu.com/p/...
java Concurrent Programming Art

Keywords: Java Mobile Programming shell

Added by davidlenehan on Fri, 12 Jun 2020 09:03:54 +0300