Procedure, process, thread connection and distinction

In fact, a program is a static code, it is the application of the execution of the script. Process is the dynamic execution process of the program, which has dynamic, concurrent and independent character. A thread is a unit of process scheduling and execution.

Process: Each process has its own code and data space (process context). A process contains one or more threads, and threads are the smallest unit of resource allocation.

Thread: The same type of thread shares code and data space, and each thread has its own running stack and program counter, and the thread is the smallest unit of scheduling.

So what is multiprocess? , it is common to open our own computer task manager there will be multiple processes, in fact, refers to our operating system can run multiple tasks at the same time (wechat, QQ, etc.).

Multithreading is simply a process with multiple paths running.

Second, the way to achieve multithreading

There are three ways to implement multithreading in Java, the first way is to inherit Thread class, the second way is to implement Runnable interface, the third way is to implement Callable, combined with Future use (understand), concurrent programming, here does not specify:

The first way to achieve multithreading, Thread class inheritance, code implementation is as follows:

public class RabbitDemo extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println("The rabbit ran away."+i+"Step");
        }
    }
}
public class TortoiseDemo extends Thread {
    @Override
    public void run() {
        for (int i = 0; i <10 ; i++) {
            System.out.println("The turtle ran away."+i+"Step"); } } } public class ClientThreadTest { public static void main(String[] args) { RabbitDemo rabbitDemo = new RabbitDemo();  TortoiseDemo tortoiseDemo = new TortoiseDemo(); rabbitDemo.start(); tortoiseDemo.start();for (int i = 0; i < 10; i++) {
            System.out.println("main==>"+ i); }}}Copy the code

The second example implements the running state of multiple threads sharing a member variable thread at the same time.

public class Qp12306 implements Runnable {
    private int num=50;
    @Override
    public void run() {
        while (true) {if (num<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"Grab the tickets"+num--);
        }
    }
}
public class ClientQpTest {
    public static void main(String[] args) {
        Qp12306 qp12306 = new Qp12306();
        Thread thread = new Thread(qp12306, "Zhang");
        Thread thread1 = new Thread(qp12306, "Bill");
        Thread thread2 = new Thread(qp12306, "Fifty"); thread.start(); thread1.start(); thread2.start(); }}Copy the code

The second way: implement the Runnable interface, rewrite the run method, this way we implement the common way of multithreading (avoid Java single inheritance restrictions) and this way using the static proxy design pattern (see: static proxy), code example is as follows:

public class RunnableDemo implements Runnable {

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("Runnable:"+ i); } } } public class ClientRunableTest { public static void main(String[] args) { RunnableDemo runnableDemo = new RunnableDemo(); Thread thread = new Thread(runnableDemo); thread.start(); }}Copy the code

Third way: to implement the Callable interface, combined with the Future to achieve multi-threading, code examples are as follows:

/** * public class implements Callable<Integer> {private String name; private long time; // Delay time private Boolean flag =true; private int step = 0; @override public Integer Call () throws Exception {while (flag) {
            Thread.sleep(time);
            step++;
        }
        return step;
    }

    public Race(String name, long time) {
        this.name = name;
        this.time = time;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}
public class CallableTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService executorService = Executors.newFixedThreadPool(2);
        Race race = new Race("Zhang", 200);
        Race race1 = new Race("Bill", 500);
        Future<Integer> result = executorService.submit(race);
        Future<Integer> result1 = executorService.submit(race1);
        Thread.sleep(3000);
        race.setFlag(false);
        race1.setFlag(false);
        int num1 = result.get();
        int num2 = result1.get();
        System.out.println("Zhang SAN -- -- >" + num1 + "Step");
        System.out.println("Li si - >" + num2 + "Step"); / / stop service executorService shutdownNow (); }}Copy the code

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.

Conclusion:

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

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

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

3, increase the robustness of the program, the code can be shared by multiple threads, code and data independence

4. Thread pools can only be placed in classes that implement Runable or Callable threads, not directly in classes that inherit threads

The main method is actually a thread. In Java, all threads are started at the same time, and when and which are executed first depends on who gets the CPU resources first.

In Java, at least two threads are started each time a program runs. One is the main thread and the other is the garbage collector thread. Because every time a class is executed using a Java command, a JVM is actually started, and each JVM is starting a process in the operating system.

State and method of thread

A thread is always in one of five states from creation to execution: New state, ready state, running state, blocked state, dead state. A thread has the following five states:

Thread Thread = new Thread();

2. Runnable state: Also known as the “executable state”. When a thread is new, another thread calls the object’s start() method, namely thread.start(). A process that enters the ready state has all the resources it needs to run except the CPU.

3. Running: The thread obtains CPU permission and starts to execute. Note: A thread can only go from ready to run.

Bloacked: BLOCKED is when a thread gives up access to the CPU for some reason and stops running until it is ready to run again.

There are three types of blocking:

(1) Wait blocking: A running thread performs wait(), which releases all resources occupied by the thread, and the JVM places the thread in the “wait pool.” This state cannot be woken up automatically. Other threads must call notify() or notifyAll() to wake up. (2) Synchronized blocking: When a running thread acquires a synchronized lock that is occupied by another thread, the JVM pools that thread into a synchronized lock pool. (3) Other blocking: the thread will enter the blocking state by calling its sleep() or join() or issuing an I/O request. When the sleep() state times out, the join() wait thread terminates or times out, or the I/O process is complete, the thread returns to the ready state 5. Dead: A thread terminates its life cycle when it finishes executing or exits the run() method because of an exception.

Blocking thread methods:

Wait (),notify (), and notifyAll() are methods that are used together and belong to Object. Wait is used when the current thread releases the lock it holds and enters the wait state. Notify and notifyAll wake up the waiting thread on the current object. Wait () — To hold the current thread in the “wait(blocking) state” until another thread calls notify() or notifyAll() of this object and the current thread is awakened (in the “ready state”).

The sleep() and yield() methods belong to the Thread class. The sleep() function is to put the current Thread to sleep(the executing Thread voluntarily gives up its CPU so that the CPU can perform other tasks). That is, the current Thread goes from “running” to “blocking” but still holds the object lock and still holds the lock. When the delay time expires, the thread reblocks and becomes ready to wait for the CPU’s scheduled execution. Sleep () Holds the object lock while it is asleep and still holds the lock. Yield () acts as a concession, allowing the current thread to move from the running state to the ready state, “allowing other waiting threads to acquire execution rights. However, there is no guarantee that other threads will gain execution rights after the current thread calls yield(), or that the current thread may return to the” running state “and continue running.

The difference between wait () and sleep() :

1. Each object has a lock to control synchronous access. The Synchronized keyword can interact with an object’s lock to achieve thread synchronization. The sleep method does not release the lock, while the wait method releases the lock, allowing other threads to use the synchronized control block or method. Sleep must catch exceptions. Wait,notify, and notifyAll do not catch exceptions. Sleep () Wait () releases the object lock while holding the lock.

Basic thread information and priority

Methods involving threads are as follows: thread.currentthread () the currentThread, setName(): sets the name, getName(): obtains the name, isAlive(): determines the status priority: Java threads have a priority, and threads with a higher priority get more running opportunities. The priority of a Java Thread is an integer ranging from 1 to 10. The Thread class has the following three static constants: static int MAX_PRIORITY The highest priority that a Thread can have. The value is 10. Static int MIN_PRIORITY Minimum priority that a thread can have. The value is 1. Static int NORM_PRIORITY Specifies the default priority assigned to a thread. The value is 5.

The following code is implemented: Basic information

public static void main(String[] args) throws InterruptedException {
        Rundemo rundemo = new Rundemo();
        Thread thread = new Thread(rundemo);
        thread.setName("Thread"); System.out.println(thread.getName())); System.out.println(thread.currentThread ().getName())); / / main thread thread. The start (); System.out.println("Thread status after starting:"+ thread.isAlive()); Thread.sleep(10); rundemo.stop(); Thread.sleep(1000); System.out.println(system.out.println ("State after a thread has stopped:" + thread.isAlive());
        test(a); }Copy the code

priority

public static void test() throws InterruptedException {
        Rundemo rundemo1 = new Rundemo();
        Thread thread1 = new Thread(rundemo1);
        thread1.setName("Thread thread1");
        Rundemo rundemo2 = new Rundemo();
        Thread thread2 = new Thread(rundemo2);
        thread2.setName("Thread thread2");
        thread1.setPriority(Thread.MAX_PRIORITY);
        thread2.setPriority(Thread.MIN_PRIORITY);
        thread1.start();
        thread2.start();
        Thread.sleep(1000);
        rundemo1.stop();
        rundemo2.stop();

    }

Copy the code

5. Thread synchronization and deadlocks

Synchronization methods: synchronized synchronized code block: synchronized (reference type | this | classes. The class) {} thread synchronization for multiple threads access a resource to ensure correct data at the same time, will not result in a pile of data read, deadlock is caused by waiting for locks lock each other between threads.

Synchronized is used by multiple threads accessing a resource simultaneously

public class Qp12306 implements Runnable {
    private int num = 10;  
    private boolean flag = true;

    @Override
    public synchronized void run() {
        while (true) {
            test(a); } } public synchronized voidtest() {
        if (num <= 0) {
            flag = false;
            return;
        }
        System.out.println(Thread.currentThread().getName() + "Grab the tickets" + num--);
    }
}

public class ClientQpTest {
    public static void main(String[] args) {
        Qp12306 qp12306 = new Qp12306();
        Thread thread = new Thread(qp12306, "Zhang");
        Thread thread1 = new Thread(qp12306, "Bill");
        Thread thread2 = new Thread(qp12306, "Fifty"); thread.start(); thread1.start(); thread2.start(); }}Copy the code

The results

Synchronized static code block

public class Client {
    public static void main(String[] args) throws InterruptedException {
        JvmThread thread1 = new JvmThread(100);
        JvmThread thread2 = new JvmThread(500);
        thread1.start();
        thread2.start();


    }

}

class JvmThread extends Thread{
    private long time;
    public JvmThread() {
    }
    public JvmThread(long time) {
        this.time =time;
    }
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-- - > create."+Jvm.getInstance(time)); }} /** * singleton design pattern * Ensure that a class has only one object * lazy * 1, private constructor, avoid external direct creation of the object * 2, declare a private static variable * 3, create an external public static method to access the variable, if the variable has no object, */ class Jvm {// Declare a private static variable private static Jvm instance =null; // The constructor is privatized to avoid creating the object private directly from outsideJvmPublic static Jvm getInstance(long time){public static Jvm getInstance(long time){if(null==instance){
            synchronized(Jvm.class){
                if(null==instance ){ try { Thread.sleep(time); } catch (InterruptedException e) { e.printStackTrace(); } instance =new Jvm(); }}}return instance;
    }


    public static Jvm getInstance3(long time){
        synchronized(Jvm.class){
            if(null==instance ){
                try {
                    Thread.sleep(time); 
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                instance =new Jvm();
            }
            returninstance; }}}Copy the code

Producer-consumer model

Producer and consumer problem is a classic problem in threading model: Producers and consumers share the same storage space in the same period of time. As shown in the figure below, producers store data in the space while consumers take data. If there is no coordination, the following situation may occur: Storage space is full, producers are occupying it, consumers are waiting for producers to give up space to get rid of products, producers are waiting for consumers to consume products, to add products to space. They wait for each other, resulting in a deadlock.

The specific implementation code is as follows:

/** * public class implements Runnable {private Movie Movie; public ProduceRu(Movie movie) { this.movie = movie; } @Override public voidrun() {
        for (int i = 0; i < 10; i++) {
            if (0 == i % 2) {
                movie.proTest("The life of desire.");
            } else {
                movie.proTest("The Voice"); }}}} /** * consumer */ public class ConsumeRu implements Runnable {private Movie Movie; public ConsumeRu(Movie movie) { this.movie = movie; } @Override public voidrun() {
        for(int i=0; i<10; i++){ movie.conTest(); }} /** * The producer-consumer pattern accesses the same resource *waitSleep () does not release lock * notify()/notifyAll(): wake */ public class Movie {private String PIC; //flag--->trueThe producer produces, the consumer waits, and notifies the consumer when the production is finished.falsePrivate Boolean flag = The consumer consumes, the producer waits, and notifies the producer when the consumer finishes consumingtrue; @param PIC */ public synchronized void proTest(String PIC) {if(! flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Produced:" + pic);
        this.pic = pic;
        this.notify();
        this.flag = false; } /** * public synchronized void */ synchronized voidconTest() {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Consumer:" + pic);
        this.notifyAll();
        this.flag = true; } } public class ClientTest { public static void main(String[] args) { Movie movie=new Movie(); new Thread(new ProduceRu(movie)).start(); new Thread(new ConsumeRu(movie)).start(); }}Copy the code

7. Task scheduling

This is the most common way to implement a Thread. Create a Thread and let it run in a while loop. Sleep is used to implement a timed task. This can be quickly and easily implemented with the following code:

public class ThreadTest {
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                try {
                    System.out.println("Mission has begun.");
                    while (true) {
                        Thread.sleep(1000);
                        System.out.println("hello"); } } catch (InterruptedException e) { e.printStackTrace(); }}}; Thread thread = new Thread(runnable); thread.start(); }}Copy the code

The Thread method has the advantages of simplicity, but lacks flexibility. The two main advantages of the TimeTask implementation method are that the time for starting and canceling tasks can be controlled, and the desired delay time can be specified when the task is executed for the first time. In the implementation process, Timer is used to schedule tasks, TimeTask user specific implementation, is thread safe, the code is as follows:

public class TimeTest {

    public static void main(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("Task run......."); } },new Date(),1000); }}Copy the code

3. ScheduledExecutorService ScheduledExecutorService realization method from Java Java. Util. In concurrent compared with the two methods, it has the following benefits: Compared with the single thread of Timer, it executes tasks in the way of thread pool, which can flexibly set the delay time for the first execution of tasks. The specific code is as follows:

ScheduledFuture<? > scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit) creates and executes periodic actions that are first enabled after a given initialDelay, The subsequent given delay between the termination of one execution and the beginning of the next. If the execution of a task encounters an exception, subsequent execution is suppressed. Otherwise, the task will be terminated only by canceling or terminating the executor. Parameter command – The task to be executed initialDelay – To delay the first execution (that is, how long the first time to specify the timing delay), In the code I delay 10 seconds delay – The delay between the end of one execution and the start of the next unit-initialdelay and the time unit of the delay parameter


public class ScheduledExecutorServiceTest {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
        scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("Mission !!!!"); }}, 10000100, TimeUnit. MILLISECONDS); }}Copy the code

Conclusion: After reading what do not understand welcome to leave a comment below!