Justin의 개발 로그

https://github.com/Justin-ad-Park/fastcampus-mysql/tree/init/project

 

GitHub - Justin-ad-Park/fastcampus-mysql

Contribute to Justin-ad-Park/fastcampus-mysql development by creating an account on GitHub.

github.com

[샘플 구동용 Gradle 설정]

plugins {
    id 'org.springframework.boot' version '2.7.2'
    id 'io.spring.dependency-management' version '1.0.12.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '16'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-data-redis'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.data:spring-data-commons:2.7.2'
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.8'
    implementation 'org.projectlombok:lombok:1.18.18'
    implementation 'org.jetbrains:annotations:20.1.0'
    implementation 'io.reactivex.rxjava3:rxjava:3.0.9'

    compileOnly 'org.projectlombok:lombok'

    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'mysql:mysql-connector-java'

    annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.jeasy:easy-random-core:5.0.0'

    testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.2")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.2")
    testRuntimeOnly('org.junit.platform:junit-platform-engine:1.8.2')
    testRuntimeOnly('org.junit.platform:junit-platform-commons:1.8.2')

}

tasks.named('test') {
    maxHeapSize = "2048m"
    useJUnitPlatform()
}

 

[코드 : ThreadPerSecondWithFracefullyShutdown]

package com.example.reactiveprogramming.bestpractice;

import com.example.javaLang.generic.basic.JSUtils;
import org.apache.commons.lang3.time.StopWatch;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class ThreadPerSecondWithGracefullyShutdown {
    private static final int MAX_API_CALLS_PER_SECOND = 5;
    private static final int ONE_SECOND_UNIT_MS = 1000;

    @Test
    void test() {
        StopWatch sw = JSUtils.startStopWatch();

        /** Given
         * Create a list of 1000 integers
         * Create an iterator from the list
         * */
        List<Integer> data = new ArrayList<>();
        for (int i = 1; i <= 100; i++) {
            data.add(i);
        }

        Iterator<Integer> dataIterator = data.iterator();

        // Create a ExecutorService(Threads)
        ExecutorService executor = Executors.newFixedThreadPool(MAX_API_CALLS_PER_SECOND);

        while(dataIterator.hasNext()) {
            int value = dataIterator.next();

            // Start the scheduled task
            executor.submit(() -> {
                    System.out.println("Thread call :" + value);
                    call(value);
            });
        }

        System.out.println("Executor.shutdown()");

        // Shut down the executor gracefully
        executor.shutdown();

        try {
            // Wait for the executor to finish all tasks for up to 1 hour
            if (!executor.awaitTermination(1, TimeUnit.HOURS)) {
                // If not all tasks finished, force them to shut down
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            // If the main thread was interrupted while waiting, force shutdown
            executor.shutdownNow();
            // Preserve interrupt status
            Thread.currentThread().interrupt();
        }

        JSUtils.printCurrentStopWatch(sw);

        System.out.println("All tasks completed");
    }


    // Assuming the external API accepts an integer and returns a string
    public void call(int input) {
        try {
            /**
             * 초당 API Call 횟수 초과를 방지하기 위해 1초 대기
             * 이 대기로 인해 초당 호출 건수를 초과하지 않을 수 있다.
             *
             * 초당 호출 건수 제한 = 스레드수
             */
            Thread.sleep(ONE_SECOND_UNIT_MS);

            // API Call 호출 응답 시간 강제 생성.
            Long rnd = 100 + getRandom(1000L);
            Thread.sleep(rnd);


            System.out.println(Thread.currentThread().getName()+ " Response for " + input + " wait : " + rnd + "ms" );
        } catch (InterruptedException e) {
            System.out.println("Failed to get a response for " + input);
        }
    }

    public static long getRandom(long maxValue) {
        Random rnd = new Random();
        return rnd.nextLong(maxValue);
    }

}

 

profile

Justin의 개발 로그

@라이프노트

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!