Multithreaded 1.22

Multithreading:

​ Multithreading refers to the inclusion of multiple execution streams in the program, which means that multiple different threads are run at the same time in a program to perform different tasks

Threads and processes:

Process: The basic unit of system resource allocation. An application running in memory

Thread: The unit of cpu scheduling and execution. An execution task in the process

Threads in the same process share the address space and resources of the process

The address space and resources between each process are independent of each other

A process crashes and will not affect other threads in protected mode

One thread crashes and the whole process dies

Three elements of concurrent programming: atomicity , visibility, and order

User thread and daemon thread:

​ User thread: run in the foreground, perform specific tasks.

​ Daemon thread: running in the background, serving user threads.

The main function is a user thread. When the main function is started, the JVM also starts many daemon threads, such as garbage collection threads.

When the user thread ends, the JVM exits, regardless of whether there is a daemon thread.

package com.zql.demo02;

public class TestDeamon {
    
    

    public static void main(String[] args) {
    
    
        //创建守护线程
        God god = new God();
        Thread thread = new Thread(god);
        //设置为守护线程
        thread.setDaemon(true);
        thread.start();
        //创建用户线程
        You you = new You();
        new Thread(you).start();
    }
}

//守护线程
class God implements Runnable{
    
    

    @Override
    public void run() {
    
    
        while (true){
    
    
            System.out.println("上帝守护你");
        }
    }
}

//用户线程
class You implements Runnable{
    
    

    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("活了" + i + "年");
        }
    }
}

Thread deadlock:

​ Deadlock refers to the blocking phenomenon of two or more processes (threads) in the execution process due to competition for resources or communication.

Four necessary conditions for deadlock:

​ 1. Mutually exclusive conditions: threads (processes) are exclusive to the allocated resources, a resource can only be occupied by one thread (process)

​ 2. Request and hold conditions: When a thread (process) is blocked because the requested resource is occupied, keep the acquired resources

​ 3. Non-deprivation conditions: the resources that the thread (process) has acquired cannot be forcibly deprived by other threads before they are used.

​ 4. Loop waiting condition: When a deadlock occurs, the waiting thread (process) will form a loop, similar to an infinite loop, causing permanent blockage

How to avoid deadlock:

​ Destroy any one of the four necessary conditions

Create thread:

1. Inherit the Thread class

​ 1. Create a Thread subclass to implement the Thread class

​ 2. Rewrite the run method

​ 3. Create a thread object, start the thread

package com.zql.demo02;

public class TestThread extends Thread {
    
    

    @Override
    public void run() {
    
    
        System.out.println("run正在执行");
    }

    public static void main(String[] args) {
    
    
        TestThread testThread = new TestThread();
        testThread.start();
        System.out.println("main正在执行");
    }
}

2. Implement the Runnable interface

​ 1. Define the class to implement the Runnable interface and override the run method

​ 2. Create a thread object

​ 3. Throw into the thread object, start the thread

package com.zql.demo02;

public class TestRunnable implements Runnable {
    
    
    @Override
    public void run() {
    
    
        System.out.println("run正在执行");
    }

    public static void main(String[] args) {
    
    
        TestRunnable testRunnable = new TestRunnable();
        new Thread(testRunnable).start();
        System.out.println("main正在执行");
    }
}

3. Implement the Callable interface

​ 1. Create an implementation class to implement the Callable interface and define the return value type

​ 2.new FutureTask creates thread object

​ 3. Throw into the thread object, call start () to start the thread

package com.zql.demo02;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestCallable implements Callable<Integer> {
    
    
    @Override
    public Integer call() throws Exception {
    
    
        System.out.println("call执行");
        return 1;
    }

    public static void main(String[] args) throws InterruptedException, ExecutionException {
    
    
        FutureTask<Integer> integerFutureTask = new FutureTask<>(new TestCallable());
        new Thread(integerFutureTask).start();

        Thread.sleep(1000);
        System.out.println("获得返回值:" + integerFutureTask.get());

        System.out.println("main执行");
    }
}

The difference between Runnable and Callable:

​ Similarities:

​ 1. All are interfaces

​ 2. Both can write multi-threaded programs

​ 3. All start with start()

​ Difference:

​ 1. Runnable interface run method has no return value, Callable interface call method has return value, it is a generic

​ 2. The run method of the Runnable interface can only throw runtime exceptions and cannot be caught; the call method of the Callable interface can throw exceptions

The Callable interface supports returning the execution result, which needs to be obtained by calling FutureTask.get(). This method will block the main program from running

What is the difference between run() and start():

​ start() is used to start the thread, run() is just a function

​ start() can only be called once, run() can be called countless times

​ Call start() to start the thread, which truly realizes multithreaded operation.

​ Call run() directly, which is equivalent to calling an ordinary function

The run() method will be executed when the start() method is called, why not call the run() method directly?

A new Thread, the thread is in the newly created state. Call the start() method to start the thread and make the thread enter the ready state, and it can run when the CPU allocates time slices. Run() is called automatically.

Calling run() directly means that run() is executed as an ordinary method, not multithreaded.

Calling start() will make the thread enter the ready state, calling run() is just a common method in thread.

Common methods:

1. Stop the thread through the external flag.stop()

package com.zql.demo02;

public class TestStop implements Runnable {
    
    

    //1.设置一个外部标识位
    private boolean flag = true;

    @Override
    public void run() {
    
    
        int j = 0;
        System.out.println("run执行---" + j++);
    }

    //2.设置一个停止方法
    public void stop(){
    
    
        this.flag = false;
    }

    public static void main(String[] args) {
    
    

        //3.创建线程对象
        TestStop testStop = new TestStop();
        //4.开启线程
        new Thread(testStop).start();
        //5.在规定下停止线程
        for (int i = 0; i < 50; i++) {
    
    
            System.out.println("main执行---" + i);
            if (i == 30){
    
    
                testStop.stop();
                System.out.println("线程停止");
            }
        }

    }
}

2. Thread sleep simulation countdown

package com.zql.demo02;

public class TestSleep {
    
    

    public static void main(String[] args) {
    
    
        try {
    
    
            tenDown();
        } catch (InterruptedException e) {
    
    
            e.printStackTrace();
        }
    }


    public static void tenDown() throws InterruptedException {
    
    
        int num = 10;
        while (true){
    
    
            Thread.sleep(1000);
            System.out.println(num--);
            if (num <= 0){
    
    
                break;
            }
        }
    }
}

3. Thread polite yield()

​ Politeness may not be successful, depending on CPU scheduling

package com.zql.demo02;

public class TestYield implements Runnable {
    
    
    @Override
    public void run() {
    
    
        System.out.println(Thread.currentThread().getName() + "---线程开始");
        Thread.yield();
        System.out.println(Thread.currentThread().getName() + "---线程开始");
    }

    public static void main(String[] args) {
    
    
        TestYield testYield = new TestYield();
        new Thread(testYield,"thread1").start();
        new Thread(testYield,"thread2").start();
    }
}

4. Enforce join()

package com.zql.demo02;

public class TestJoin implements Runnable {
    
    
    @Override
    public void run() {
    
    
        for (int i = 0; i < 100; i++) {
    
    
            System.out.println("run线程---" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();

        for (int i = 0; i < 100; i++) {
    
    
            if (i == 30){
    
    
                thread.join();
            }
            System.out.println("main线程---" + i);
        }
    }
}

Thread Pool:

​ Thread pool is to create several executable threads in advance and put them into a container, get them from the container when needed, and do not need to destroy them after use, thus reducing the overhead of creating and destroying objects.

Use the tool class Executors to generate some commonly used thread pools:

​ 1.newSingleThreadExecutor creates a single-threaded thread pool

​ 2.newFixedThreadPool creates a fixed-size thread pool

​ 3.newCachedThreadPool creates a cacheable thread pool

​ 4.newScheduledThreadPool creates a thread pool of unlimited size

package com.zql.demo02;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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

    public static void main(String[] args) {
    
    
        //创建线程池    参数为线程池大小
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        executorService.execute(new TestPool());
        executorService.execute(new TestPool());
        executorService.execute(new TestPool());
        executorService.execute(new TestPool());

        //关闭连接
        executorService.shutdown();
    }
}

Guess you like

Origin blog.csdn.net/weixin_50960900/article/details/112983221