Pensamiento de back-end ---- rendimiento de optimización paralela

Tabla de contenido

fondo

lograr

fondo

Hoy aprendí la diferencia entre ejecución lineal y ejecución paralela.

Si desea consultar información diferente en diferentes bibliotecas al mismo tiempo, los amigos normales escribirían así:

public AppHeadInfoResponse queryAppHeadInfo(AppInfoReq req) {     //查     UserInfoParam userInfoParam = buildUserParam(req);     UserInfoDTO userInfoDTO = userService.queryUserInfo(userInfoParam);     //查     BannerParam bannerParam = buildBannerParam(req);     BannerDTO bannerDTO = bannerService.queryBannerInfo(bannerParam);     //查     LabelParam labelParam = buildLabelParam(req);     LabelDTO labelDTO = labelService.queryLabelInfo(labelParam);     //     return buildResponse(userInfoDTO,bannerDTO,labelDTO); }











 Es muy razonable y no tiene nada de malo, pero para optimizar el backend, hoy aprendí el modo paralelo.

¿Por qué esto es tan?

Por ejemplo, la primera consulta tarda 100 segundos, la segunda consulta tarda 90 segundos y la tercera consulta tarda 80 segundos. Si esto continúa, tardará 270 segundos. Si se paraleliza, 100 segundos serán suficientes. Incluso si no se puede completar por completo paralelizado, definitivamente será más rápido.

lograr

CompletionServiceEnvuelve ExecutorServicela definición para que pueda generar la tarea y obtener el valor de retorno de la tarea al mismo tiempo. Deje que estas dos cosas se ejecuten por separado, las tareas no se bloquearán entre sí y se podrá obtener el resultado de la primera tarea completada.

CompletionServiceEl principio de implementación es relativamente simple: la capa inferior utiliza la cola de bloqueo FutureTask + para darse cuenta de que si la tarea se completa primero, se puede obtener primero. Es decir, los resultados de la ejecución de la tarea se clasifican según el orden de finalización y las tareas que se completan primero se pueden obtener primero. Hay una cola de bloqueo de primero en entrar, primero en salir, que se utiliza para guardar el futuro completo. Puede CompletionServiceobtener un futuro completo llamando al método de encuesta o toma, y ​​luego getllamando al método del futuro para obtener el resultado final. clase de implementación de interfaz .

Basado en esto, aquí hay un caso de uso: (ejecutar el bloque de código usando la función de Fibonacci calculada)

import java.util.concurrent.*;

public class Test {
    public static void main(String[] args) {
        test1();
        System.out.println("------------------------------");
        test2();
    }

    public static void test2() {
        long beginTime = System.currentTimeMillis();
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletionService<Object> completionService = new ExecutorCompletionService<>(executor);
        Callable<Object> taskList = () -> fibonacci(40);
        Callable<Object> taskList1 = () -> fibonacci(40);
        Callable<Object> taskList2 = () -> fibonacci(40);

        completionService.submit(taskList);
        completionService.submit(taskList1);
        completionService.submit(taskList2);
        try {
            //因为提交了3个任务,所以获取结果次数是3
            for (int i = 0; i < 3; i++) {
                Future<Object> baseRspDTOFuture = completionService.poll(1, TimeUnit.SECONDS);
                Object o = baseRspDTOFuture.get();
                System.out.println("o");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        System.out.println("------------------------");
        System.out.println("总时长:" + (System.currentTimeMillis() - beginTime));
        System.exit(0);
    }
    public static void test1() {
        long beginTime = System.currentTimeMillis();
        fibonacci(40);
        long secondTime = System.currentTimeMillis();
        System.out.println("1使用时间:" + ( secondTime - beginTime ));
        fibonacci(40);
        long thirdTime = System.currentTimeMillis();
        System.out.println("2使用时间:" + (thirdTime-secondTime));
        fibonacci(40);
        System.out.println("3使用时间:" + (System.currentTimeMillis() - thirdTime)  + "总时长:" + (System.currentTimeMillis() - beginTime));
    }

    public static int fibonacci(int n) {
        if (n <= 1) {
            return n;
        } else {
            return fibonacci(n - 1) + fibonacci(n - 2);
        }
    }
}

Publique algunos resultados en ejecución:

1 Tiempo de uso: 578
2 Tiempo de uso: 577
3 Tiempo de uso: 486

Duración total: 1641
---------------------------------
Duración total: 607

1 Tiempo de uso: 615
2 Tiempo de uso: 518
3 Tiempo de uso: 377

Duración total: 1510
---------------------------------
Duración total: 574

 El efecto es notable.

Aprendí algo nuevo hoy!

-------------------------------------------------- -------------------------------------------------- -----------------------

El artículo está tomado de la cuenta pública del hermano Tianluo.

Supongo que te gusta

Origin blog.csdn.net/Yoke______/article/details/132718686
Recomendado
Clasificación