Summary of java threads (intermediate and advanced)

What is a process:

        You understand it as a software

What is a thread:

        You understand it as a function in the software, what it does

What is multithreading:

        ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​ ​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​: A certain function in the software used to be completed by one person exhaustingly. Now it’s better. Multiple people can complete it together, easily and happily.

What is thread unsafe:

        You understand it as a certain function in the software. It was originally completed by one person working hard. Although it was tiring, the data would not be wrong. But now multiple people work on it together. As a result, Zhang San read The data is the data modified by Li Si, not the latest data, so it is thread unsafe.

What is thread safety:

         You understand it as a certain function in the software. It used to be completed by one person working hard. Although it was tiring, the data would not be wrong. But now multiple people are working on it together. I asked you to line up. Manipulate the data one by one in an orderly manner. If someone is operating, I will ask you to wait outside. You must wait until the people in front have finished their work before you can go in.

What is parallelism:

        You understand it as a certain function in the software that performs multiple tasks at the same time

What is concurrency:

        You understand it as a certain function in the software. Many requests come in all at once. If they are not processed, it will cause the program to crash, freeze, etc.

Thread unsafe and thread safe,

ExampleArrayList HashSet HashMap

ArrayLists is thread-unsafe; Vector, Collections, CopyOnWriteArrayList Thread-safe

HashSet is thread-unsafe; CopyOnWriteArraySet Thread-safe

HashMap is thread-unsafe; ConcurrentHashMap Thread-safe

Let’s use code to simulate multi-threading.

Requirements: Four conductors are required to sell tickets and lock them

package com.japhet.util;

//卖票
class Ticket{

    //总票数
    private int ticket = 3000;

    //卖票逻辑递减
    public synchronized void seal(){
        if(ticket<=0){
            return;
        }
        ticket--;
        System.out.println(Thread.currentThread().getName()+"票还剩余"+ticket);
    }

}

public class ThreadUtils {
    public static void main(String[] args) {

        Ticket ticket = new Ticket();
        //售票员1进行卖票
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 4000; i++) {
                    ticket.seal();
                }
            }
        },"AA").start();
        //售票员2进行卖票
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 4000; i++) {
                    ticket.seal();
                }
            }
        },"BB").start();

        //售票员3进行卖票
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 4000; i++) {
                    ticket.seal();
                }
            }
        },"CC").start();

        //售票员4进行卖票
        new Thread(()->{
            for (int i = 0; i < 4000; i++) {
                ticket.seal();
            }
        },"DD").start();

    }
}

The following code is used to simulate the communication between threads.

Requirement: Because it is multi-threaded, when the 11th thread grabs the resource and executes its own program, it does not know who will successfully grab the resource next time. Then I can set who can grab the resource (waiting through await signal notifies a thread to execute), here let thread 11 execute, let thread 22 execute, thread 22 execute, thread 33 execute, thread 33 execute, thread 11 execute, loop this action 10 times in sequence.

package com.japhet.util;

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

class Srouce{
//    线程标识
    private int temp = 1;

//    锁
    private Lock lock =  new ReentrantLock();

//    三个线程
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void test(){
        lock.lock();
        try {
            while (temp!=1){//防止虚假唤醒,所以得用while循环
                condition1.await();
            }

            System.out.println("线程1111进来了");

            temp = 2;//修改标识,
            condition2.signal();//通知线程2去干活
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void test2(){
        lock.lock();
        try {
            while (temp!=2){//防止虚假唤醒,所以得用while循环
                condition2.await();
            }
            System.out.println("线程2222进来了");
            temp = 3;//修改标识,
            condition3.signal();//通知线程2去干活
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void test3(){
        lock.lock();
        try {
            while (temp!=3){//防止虚假唤醒,所以得用while循环
                condition3.await();
            }
            System.out.println("线程3333进来了");
            temp = 1;//修改标识,
            condition1.signal();//通知线程2去干活
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }
}

public class ThreadUtils2 {
    public static void main(String[] args) {
        Srouce srouce = new Srouce();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                srouce.test();
            }
        },"11").start();

        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                srouce.test2();
            }
        },"22").start();


        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                srouce.test3();
            }
        },"33").start();
    }

}

What is deadlock

Multiple threads perform operations simultaneously

Thread A holds lock A

Thread B holds lock B

The program is still in progress and the lock has not been released. Then thread A wants to obtain the content of thread B. At the same time, thread B also wants to obtain the content of thread A. At this time, threads A and B are in the process of waiting for each other, so It will fall into an endless loop. You wait for me to release, and I will wait for you to release again.

What are fair locks and unfair locks

Unfair lock: (fast, high efficiency)

        For example, I have three threads A, B, and C. When I run it, thread A may have strong capabilities. Then after a set of programs is run, thread A has a much higher probability of running, while the other threads B and C basically do not move much. Will starve to death, this is the concept of unfair lock

Fair lock: (slow, low efficiency)

        For example, I have three threads A, B, and C. When I run it, it will be distributed to each thread relatively fairly. See the source code. 

 

FutureTask future task demo

package com.japhet.util;

import java.util.concurrent.FutureTask;

public class FutureTaskDemo {
    public static void main(String[] args) {
        System.out.println("主线程开始....."+Thread.currentThread().getName());
        FutureTask<Integer> futureTask = new FutureTask<>(()->{
            System.out.println("--------"+Thread.currentThread().getName());
            return 1;
        });
        new Thread(futureTask).start();
        try {

            while (!futureTask.isDone()){
                System.out.println("线程还没有执行完,等待...."+Thread.currentThread().getName());
            }


            Integer num = futureTask.get();
            Integer num2 = futureTask.get();

            System.out.println("最后结果 "+num);
            System.out.println("最后结果2 "+num2);

            System.out.println("主线程结束....."+Thread.currentThread().getName());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

renderings

What is a blocking queue (BlockingQueue)

The so-called queue: that is, first in, first out, and the queue has a size limit

Thread A can put elements into the queue, and thread B can get the elements in the queue. If the queue elements are filled up by thread A, it will be blocked; if thread B has finished getting the data in the queue, it will also be blocked. 

What is a thread pool (Executors)

To avoid wasting resources, open a thread when it is in use and close it when it is not in use. Such frequent switching will cause a waste of resources.

Create thread pool

package com.japhet.util;

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

public class ThreadPoolDemo {

    public static void main(String[] args) {
        // 定义线程池里面初始化10个线程
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        // 定义线程池里面就1个线程
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
        //定义线程池里面就n个线程,可扩容,根据你调用
        ExecutorService executorService3 = Executors.newCachedThreadPool();
        try {
            for (int i = 0; i < 20; i++) {
                final int x = i;
//                executorService.execute(()->{
//                executorService2.execute(()->{
                executorService3.execute(()->{
                    System.out.println(x+"线程---"+Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
//            关闭
//            executorService.shutdown();
//            executorService2.shutdown();
            executorService3.shutdown();
        }
    }
}

(Note: It is not recommended to use these three methods to create a thread pool, because the Alibaba Java Development Manual mentions that if you use these three methods to create a thread pool, it will cause OOM Memory overflow will accumulate a large number of requests and there will be no time to process them. Generally, you create a thread pool yourself and pass in 7 parameters)

What are the types of thread pools created in Java, why thread pools are used, and rejection strategies

Why use a thread pool: There is no need to repeatedly create and destroy threads, because it consumes more resources, improves manageability, and provides unified allocation, tuning and monitoring.

newSingleThreadPool、newFixedThreadPool、newCachedThreadPool、newScheduledThreadPool、newWorkStealingPool

Parameters inside:

corePoolSize : Indicates the number of core threads in the thread pool. When the thread pool is initialized, a core thread will be created to enter the waiting state. Even if it is idle, the core thread will not be destroyed. , thereby reducing the time and performance overhead of creating a new thread when the task comes.

maximumPoolSize : Indicates the maximum number of threads, which means that the number of core threads has been used up. Then new threads can only be re-created to perform tasks, but the premise is that the maximum number of threads cannot be exceeded. Quantity, otherwise the task can only enter the blocking queue and wait in line until a thread is idle before the task can continue to be executed.

keepAliveTime : Indicates the thread survival time. In addition to the core thread, how long can newly created threads survive. This means that once these new threads complete their tasks and are idle thereafter, they will be destroyed after a certain period of time.

unit : survival time unit.

workQueue: Represents the blocking queue of tasks. Since there may be many tasks and only a few threads, the tasks that have not yet been executed will be queued in the queue. We know that the queue is FIFO. When the thread is idle, it will be This way tasks are taken out. This generally does not require us to implement it.

threadFactoy: Line Process Factory

Rejection strategy (handler): When the workqueue is full and maximumPoolSize is also full, new threads should be rejected. There are four common rejection strategies

ThreadPoolExecutor.AbortPolicy: Discards the task and throws RejectedExecutionException.

ThreadPoolExecutor.DiscardPolicy: Discards the task but does not throw an exception.

ThreadPoolExecutor.DiscardOldestPolicy: Discard the frontmost task of the queue and then resubmit the rejected task

ThreadPoolExecutor.CallerRunsPolicy: The task is processed by the calling thread (the thread that submitted the task)

Custom thread pool

package com.japhet.util;

import java.util.concurrent.*;


//创建自定义线程池,
// 只能处理 循环里面的前8个,后面的12个就被拒绝策略给拒绝了
public class ThreadPoolDemo2 {

    public static void main(String[] args) {
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(2,
                5,
                2L,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(3),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        try {
            for (int i = 0; i < 20; i++) {
                final int x = i;
                threadPoolExecutor.execute(()->{
                    System.out.println(x+"线程---"+Thread.currentThread().getName());
                });
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            threadPoolExecutor.shutdown();
        }

    }
}

Guess you like

Origin blog.csdn.net/Japhet_jiu/article/details/129166010