Cuatro formas de crear subprocesos múltiples (enfoque de grupo de subprocesos)

1. Hilo integrado

2. Implementar la interfaz Rubbable

3. Implementar la interfaz invocable con FuturTask

class myThread implements Callable<Integer>{

    @Override
    public Integer call() throws Exception {
        System.out.println("come in");
        return 1024;
    }
}

public class CallableDemo {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> futureTask = new FutureTask(new myThread());
        new Thread(futureTask, "AA").start();
        Integer o = futureTask.get();
        System.out.println(o);
    }
}

4. Grupo de subprocesos

  1. Tres métodos de grupo de subprocesos de uso común (no usamos el desarrollo real que viene con el JDK) porque no podemos controlar los recursos, asumiendo una alta concurrencia y creando muchos subprocesos al mismo tiempo.
//创建一个固定线程的线程池
        ExecutorService executorService = Executors.newFixedThreadPool(3);
        //创建一个单个线程的线程池
        ExecutorService executorService2 = Executors.newSingleThreadExecutor();
        //创建一个会自动扩容的线程池
        ExecutorService executorService3 = Executors.newCachedThreadPool();

	try {
    
    
            for (int i = 0; i < 10; i++) {
    
    
                executorService3.execute(() -> {
    
    
                    System.out.println(Thread.currentThread().getName() + "*****");
                });
            }
        } catch (Exception e) {
    
    
            e.printStackTrace();
        } finally {
    
    
            executorService3.shutdown();
        }
  1. Siete parámetros importantes del grupo de subprocesos
    aquí Nota: cuando miramos el código fuente, solo encontraremos cinco parámetros aquí, por qué yo diría que son siete parámetros
    Inserte la descripción de la imagen aquí
    para ver dentro pasar siete parámetros para llamar a este
    Inserte la descripción de la imagen aquí
    Inserte la descripción de la imagen aquí
    parámetro un máximo de 2 Integer.MAX_VALUE 2147483647
    Explique los parámetros 3 4. Por ejemplo, en este método, cuando ingresa una gran cantidad de solicitudes, creará múltiples subprocesos, y si no hay tantas solicitudes en una determinada unidad de tiempo más adelante, cerrará los subprocesos que no se hayan utilizado durante una determinada unidad de tiempo. período de tiempo (por ejemplo, si está demasiado ocupado para que lo llamen para trabajar horas extras, después, no estaba ocupado y salí temprano del trabajo).
    //创建一个会自动扩容的线程池 ExecutorService executorService3 = Executors.newCachedThreadPool();
    Parámetro 7. Es decir, nuestro número máximo de hilos y nuestra cola de bloqueo están todos llenos, y se activará la estrategia de rechazo.

Inserte la descripción de la imagen aquí

Cuatro estrategias de rechazo

Inserte la descripción de la imagen aquí

Grupo de subprocesos de transformación de escritura a mano

Cree un hilo principal con un número de 2 y un máximo de 5, una cola de bloqueo de 3 y un tiempo de espera de 1 s para destruir la estrategia de bloqueo del grupo de hilos del nuevo hilo.

ExecutorService pool = new ThreadPoolExecutor(
                2,
                5,
                1L, 
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(3),
                Executors.defaultThreadFactory(), 
                new ThreadPoolExecutor.AbortPolicy());

Cómo configurar el grupo de subprocesos de manera razonable

Primero, verifique el número de núcleos en su computadora System.out.println (Runtime.getRuntime (). AvailableProcessors ());
número de núcleos + 1 = número máximo de subprocesos

completableFuture orquestación asincrónica

La ejecución de estos 6 pasos tiene una relación de dependencia, los siguientes pasos requieren que los resultados de la ejecución previa se logren mediante orquestación asincrónica.
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

 CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getName());
            int i = 10 / 4;
            System.out.println("运行结果" + i);
            return i;
        }, executorService);

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí

 CompletableFuture.supplyAsync(() -> {
    
    
            System.out.println("当前线程" + Thread.currentThread().getName());
            int i = 10 / 4;
            System.out.println("运行结果" + i);
            return i;
        }, executorService).thenRunAsync(()->{
    
    
            System.out.println("任务2启动了 ... 结束");
        },executorService);

Después de que se ejecuten las tareas 1 y 2, realice la tarea 3

future01.thenAcceptBothAsync () Esto puede recibir el resultado anterior
future01.thenCombineAsync () Esto puede definir el valor de retorno

CompletableFuture<Integer> future01 = CompletableFuture.supplyAsync(() -> {
    
    
            System.out.println("任务1线程启动了..." + Thread.currentThread().getName());
            int i = 10 / 4;
            System.out.println("运行结果" + i);
            System.out.println("任务1线程结束了..." + Thread.currentThread().getName());
            return i;
        }, executorService);

        CompletableFuture<String> future02 = CompletableFuture.supplyAsync(() -> {
    
    
            System.out.println("任务2线程启动了..." + Thread.currentThread().getName());
            System.out.println("任务2线程结束了..." + Thread.currentThread().getName());
            return "hello";
        }, executorService);

        future01.thenAcceptBothAsync(future02,(f1,f2)->{
    
    
            System.out.println("任务3开始...");
            System.out.println("之前的结果" + f1 + f2);
        },executorService);

Siempre que se complete uno de A y B, ejecute C
Inserte la descripción de la imagen aquí

Combinación multitarea

Inserte la descripción de la imagen aquí

Configurar y usar el grupo de subprocesos

package com.gulimall.product.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Configuration
public class MyThreadPoolConfig {
    
    

    @Bean
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties threadPoolConfigProperties) {
    
    
    //配置类代码
       return new ThreadPoolExecutor(
                threadPoolConfigProperties.getCoreSize(),
                threadPoolConfigProperties.getMaxSize(),
                threadPoolConfigProperties.getKeepActiveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

    }
}

Para facilitar la configuración, podemos personalizar el archivo de configuración y agregar las siguientes dependencias: Habrá avisos en el archivo de configuración.

<!--属性的提示工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
package com.gulimall.product.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@ConfigurationProperties(prefix = "gulimall.thread")
@Component
@Data
public class ThreadPoolConfigProperties {
    
    
    private Integer coreSize;
    private Integer maxSize;
    private Integer keepActiveTime;
}

@Override
    public SkuItemVo item(Long skuId) throws ExecutionException, InterruptedException {
    
    
        SkuItemVo skuItemVo = new SkuItemVo();
		//异步编排
        CompletableFuture<SkuInfoEntity> infoFuture = CompletableFuture.supplyAsync(() -> {
            //1 sku基本信息 pms_sku_info
            SkuInfoEntity info = getById(skuId);
            skuItemVo.setInfo(info);
            return info;
        }, executor);

        CompletableFuture<Void> imageFuture = infoFuture.thenAcceptAsync((res) -> {
            //2 sku图片信息
            List<SkuImagesEntity> skuImagesEntities = skuImagesService.getImagesBySkuId(skuId);
            skuItemVo.setImages(skuImagesEntities);
        }, executor);

        CompletableFuture<Void> attrFuture = infoFuture.thenAcceptAsync((res) -> {
            //3 获取spu销售属性组合
            List<ItemSaleAttrVo> saleAttrVos = skuSaleAttrValueService.getSaleAttrsBySpuId(res.getSpuId());
            skuItemVo.setSaleAttr(saleAttrVos);
        }, executor);

        CompletableFuture<Void> descFuture = infoFuture.thenAcceptAsync((res) -> {
            //4 获取spu介绍 pms_spu_info_desc
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
            skuItemVo.setDesc(spuInfoDescEntity);
        }, executor);

        CompletableFuture<Void> groupAttrFuture = infoFuture.thenAcceptAsync((res) -> {
            //5 获取spu规格参数信息
            List<SpuItemAttrGroupVo> attrGroupVos = attrGroupService.getAttrGroupWithAttrsBySpuId(res.getSpuId(), res.getCatalogId());
            skuItemVo.setGroupAttrs(attrGroupVos);
        }, executor);

        //等待所有的异步任务都完成才返回我们的结果
        CompletableFuture.allOf(imageFuture,attrFuture,descFuture,groupAttrFuture).get();
        // 6.查询当前sku是否参与秒杀优惠
        return skuItemVo;
    }

Supongo que te gusta

Origin blog.csdn.net/qq_36905956/article/details/105935388
Recomendado
Clasificación