-
Notifications
You must be signed in to change notification settings - Fork 1
@Async 메서드 사용 예시 작성 #25
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
+480
−4
Closed
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
b0222f8
✨ Feat : 새로운 기능
haxr369 fd93056
✅ Test : 테스트 코드 추가
haxr369 3c8ff75
✨ Feat : 새로운 기능
haxr369 0b829d6
Merge branch 'main' into main
haxr369 1305987
Merge remote-tracking branch 'origin/main'
haxr369 c734c16
✨ Feat : 새로운 기능
haxr369 f78aeac
✨ Feat : 새로운 기능
haxr369 b96f482
🤖 Refactor : 코드 리팩토링
haxr369 f528555
✨ Feat : 새로운 기능
haxr369 8c63b49
Merge remote-tracking branch 'concurrency/develop'
haxr369 83c6f93
✨ Feat : 새로운 기능
haxr369 0b33222
✅ Test : 테스트 코드 추가
haxr369 06cbe1f
🤖 Refactor : 코드 리팩토링
haxr369 a752e80
🐛 Fix : 오류 수정
haxr369 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
35 changes: 35 additions & 0 deletions
35
src/main/java/com/thread/concurrency/async/controller/AsyncController.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.thread.concurrency.async.controller; | ||
|
||
import com.thread.concurrency.async.service.AsyncService; | ||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Controller; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalTime; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
@Controller | ||
public class AsyncController { | ||
private final AsyncService asyncService; | ||
|
||
public AsyncController(AsyncService asyncService) { | ||
this.asyncService = asyncService; | ||
} | ||
|
||
@Async | ||
public CompletableFuture<String> calculateRunTime(int cnt, int waitTime) throws InterruptedException { | ||
LocalTime lt1 = LocalTime.now(); | ||
List<CompletableFuture<String>> hellos = new ArrayList<>(); | ||
for(int i=0; i<cnt; i++){ | ||
hellos.add(asyncService.voidParamStringReturn(waitTime,i+"번째 메세지")); | ||
} | ||
// 모든 비동기 호출이 완료될 때까지 대기하고 결과를 리스트에 넣기 | ||
List<String> results = hellos.stream().map(CompletableFuture::join) | ||
.toList(); | ||
LocalTime lt2 = LocalTime.now(); | ||
long dif = Duration.between(lt1, lt2).toMillis(); | ||
return CompletableFuture.completedFuture(dif+"가 걸렸습니다."); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/com/thread/concurrency/async/service/AsyncService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package com.thread.concurrency.async.service; | ||
|
||
import org.springframework.scheduling.annotation.Async; | ||
import org.springframework.stereotype.Service; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
|
||
|
||
@Service | ||
public class AsyncService { | ||
@Async | ||
public CompletableFuture<String> voidParamStringReturn (long waitTime, String message) throws InterruptedException{ | ||
System.out.println("비동기적으로 실행 - "+ | ||
Thread.currentThread().getName()); | ||
Thread.sleep(waitTime); | ||
return CompletableFuture.completedFuture(message); | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
src/main/java/com/thread/concurrency/counter/CompletableFutureCounter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
@Component | ||
public class CompletableFutureCounter implements Counter{ | ||
|
||
private CompletableFuture<Integer> counter = new CompletableFuture<>(); | ||
|
||
@Override | ||
public void add(int value) { | ||
// 연산이 진행 중이라면 기다렸다가 thenApply | ||
// 카운트에 값 저장 | ||
counter = counter.thenApply((c) -> c + value); | ||
} | ||
|
||
@Override | ||
public int show() { | ||
try { | ||
// 카운트에 대한 연산이 실행 중이라면 기다렸다가 가져오기 | ||
return counter.get(); | ||
} catch (InterruptedException | ExecutionException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/main/java/com/thread/concurrency/counter/SynchronizedCounter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import net.jcip.annotations.GuardedBy; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class SynchronizedCounter implements Counter{ | ||
|
||
@GuardedBy("this") | ||
private int counter = 100; | ||
|
||
@Override | ||
public synchronized void add(int value) { | ||
counter += value; | ||
} | ||
|
||
@Override | ||
public synchronized int show() { | ||
return counter; | ||
} | ||
} |
33 changes: 33 additions & 0 deletions
33
src/main/java/com/thread/concurrency/counter/producerCustomer/CounterConsumer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.thread.concurrency.counter.producerCustomer; | ||
|
||
import java.util.concurrent.BlockingQueue; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
import java.util.function.Function; | ||
import java.util.function.IntUnaryOperator; | ||
|
||
public class CounterConsumer { | ||
private final BlockingQueue<Function<Integer, Integer>> queue; | ||
private final AtomicInteger count = new AtomicInteger(100); // 스레드 안전성은 synchronized에게 맞기기 때문에 int로 변경. | ||
|
||
public CounterConsumer(BlockingQueue<Function<Integer, Integer>> queue) { | ||
this.queue = queue; | ||
} | ||
|
||
public void consumeEvent() throws InterruptedException { | ||
while (!queue.isEmpty()) { | ||
System.out.println("현재 큐 사이즈 : "+queue.size()); | ||
Function<Integer, Integer> event = queue.take(); | ||
IntUnaryOperator operator = event::apply; | ||
System.out.println("결과 카운트 : "+count.updateAndGet(operator)); | ||
} | ||
} | ||
public int show(){ // 큐가 비어지는 마지막 순간에 if문이 true가 되어 count를 출력해버린다... | ||
while(true){ | ||
if(queue.isEmpty()){ | ||
int ret = count.get(); | ||
System.out.println("정답은 ? : "+ret); | ||
return ret; | ||
} | ||
} | ||
} | ||
} |
16 changes: 16 additions & 0 deletions
16
src/main/java/com/thread/concurrency/counter/producerCustomer/CounterProducer.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.thread.concurrency.counter.producerCustomer; | ||
|
||
import java.util.concurrent.BlockingQueue; | ||
import java.util.function.Function; | ||
|
||
public class CounterProducer { | ||
private final BlockingQueue<Function<Integer, Integer>> queue; | ||
|
||
public CounterProducer(BlockingQueue<Function<Integer, Integer>> queue) { | ||
this.queue = queue; | ||
} | ||
|
||
public void add(int value) throws InterruptedException { | ||
queue.put((c) -> c + value); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/test/java/com/thread/concurrency/AsyncControllerTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.thread.concurrency; | ||
|
||
import com.thread.concurrency.async.controller.AsyncController; | ||
import org.junit.jupiter.api.Test; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
@SpringBootTest | ||
public class AsyncControllerTest { | ||
private static final Logger logger = LoggerFactory.getLogger(AsyncServiceTest.class); | ||
|
||
@Autowired | ||
private AsyncController asyncController; | ||
|
||
@Test | ||
public void invokeMultiAsyncMethod() throws InterruptedException { | ||
List<CompletableFuture<String>> hellos = new ArrayList<>(); | ||
for(int i=0; i<10; i++){ | ||
hellos.add(asyncController.calculateRunTime(10, 1000)); | ||
} | ||
// 모든 비동기 호출이 완료될 때까지 대기하고 결과를 리스트에 넣기 | ||
List<String> results = hellos.stream().map(CompletableFuture::join) | ||
.toList(); | ||
results.forEach(logger::info); | ||
} | ||
} |
52 changes: 52 additions & 0 deletions
52
src/test/java/com/thread/concurrency/AsyncServiceTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package com.thread.concurrency; | ||
|
||
import com.thread.concurrency.async.service.AsyncService; | ||
import org.junit.jupiter.api.*; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ExecutionException; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
@SpringBootTest | ||
public class AsyncServiceTest { | ||
private static final Logger logger = LoggerFactory.getLogger(AsyncServiceTest.class); | ||
@Autowired | ||
private AsyncService asyncService; | ||
|
||
@Test | ||
@DisplayName("입력은 void 출력은 String인 비동기 함수 단일 호출") | ||
public void testGetString() throws ExecutionException, InterruptedException { | ||
CompletableFuture<String> helloWorld = asyncService.voidParamStringReturn(1000, "기본 메세지"); | ||
Assertions.assertEquals("기본 메세지",helloWorld.get()); | ||
} | ||
|
||
@Test | ||
@DisplayName("입력은 void 출력은 String인 비동기 함수 다중 호출") | ||
public void testGetMultiString() throws InterruptedException { | ||
List<CompletableFuture<String>> hellos = new ArrayList<>(); | ||
for(int i=0; i<100; i++){ | ||
hellos.add(asyncService.voidParamStringReturn(1000,i+"번째 메세지")); | ||
ooMia marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
// 모든 비동기 호출이 완료될 때까지 대기하고 결과를 리스트에 넣기 | ||
List<String> results = hellos.stream().map(CompletableFuture::join) | ||
.toList(); | ||
results.forEach(logger::info); | ||
} | ||
|
||
@Test | ||
@DisplayName("입력은 void 출력은 String인 비동기 함수 단일 호출 타임아웃 발생.") | ||
public void testGetStringTimeOutIsThisAsync() throws InterruptedException { | ||
// voidParamStringReturn가 비동기 메서드인지 의문이 생김. | ||
CompletableFuture<String> completableFuture = asyncService.voidParamStringReturn(4000, "타임아웃 발생 안 함!"); | ||
long timeOutValue = 1; | ||
TimeUnit timeUnit = TimeUnit.SECONDS; | ||
// 1초가 지난 후 타임아웃 발생 | ||
Assertions.assertThrows(ExecutionException.class, () -> completableFuture.orTimeout(timeOutValue,timeUnit).get()); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
src/test/java/com/thread/concurrency/counter/BasicCounterTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
import java.util.concurrent.CompletableFuture; | ||
|
||
@SpringBootTest | ||
public class BasicCounterTest { | ||
|
||
private final BasicCounter basicCounter; | ||
private final int counteNumber = 1; | ||
private final int totalCount = 100; | ||
|
||
@Autowired | ||
public BasicCounterTest(BasicCounter basicCounter) { | ||
this.basicCounter = basicCounter; | ||
} | ||
|
||
@Test | ||
@DisplayName("스레드 안전하지 않는 카운터로 동시에 여러 더하기 수행하기. 실패 예상") | ||
public void 여러_더하기_수행(){ | ||
int initalCount = basicCounter.show(); | ||
|
||
for(int i=0; i<totalCount; i++){ | ||
CompletableFuture.runAsync(() -> { | ||
basicCounter.add(counteNumber); | ||
}); | ||
} | ||
int finalCount = basicCounter.show(); | ||
Assertions.assertNotEquals(initalCount+totalCount*counteNumber, finalCount); | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
src/test/java/com/thread/concurrency/counter/CompletableFutureCounterTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalTime; | ||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
@SpringBootTest | ||
public class CompletableFutureCounterTest { | ||
private final int counteNumber = 1; | ||
private final int totalCount = 10000; | ||
private static final Logger logger = LoggerFactory.getLogger(CompletableFutureCounterTest.class); | ||
|
||
@Test | ||
public void 여러_더하기_수행_Compltable() throws InterruptedException { | ||
SynchronizedCounter counter = new SynchronizedCounter(); | ||
LocalTime lt1 = LocalTime.now(); | ||
|
||
int initalCount = counter.show(); | ||
ExecutorService service = Executors.newFixedThreadPool(15); | ||
CountDownLatch latch = new CountDownLatch(totalCount); | ||
for (int i = 0; i < totalCount; i++) { | ||
service.submit(() -> { | ||
counter.add(counteNumber); | ||
latch.countDown(); | ||
}); | ||
} | ||
latch.await(); | ||
int finalCount = counter.show(); | ||
|
||
LocalTime lt2 = LocalTime.now(); | ||
long dif = Duration.between(lt1, lt2).getNano(); | ||
logger.info("여러_더하기_수행_Compltable 테스트가 걸린 시간 : "+dif/1000000+"ms"); | ||
Assertions.assertEquals(initalCount+totalCount*counteNumber, finalCount); | ||
} | ||
} |
58 changes: 58 additions & 0 deletions
58
src/test/java/com/thread/concurrency/counter/QueueCounterTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import com.thread.concurrency.counter.producerCustomer.CounterConsumer; | ||
import com.thread.concurrency.counter.producerCustomer.CounterProducer; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalTime; | ||
import java.util.concurrent.*; | ||
import java.util.function.Function; | ||
|
||
public class QueueCounterTest { | ||
private final int counteNumber = 1; | ||
private final int totalCount = 10000; | ||
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class); | ||
@Test | ||
@DisplayName("producer consumer 패턴을 이용해서 더하기 이벤트 발생 스레드와 더하기 이벤트 처리 스레드를 분리하자") | ||
public void 프로듀서_컨슈며_더하기_멀티_프로듀서_멀티_컨슈머() throws InterruptedException { | ||
BlockingQueue<Function<Integer, Integer>> queue = new LinkedBlockingQueue<>(1000); | ||
CounterConsumer consumer = new CounterConsumer(queue); | ||
CounterProducer producer = new CounterProducer(queue); | ||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = consumer.show(); | ||
ExecutorService service = Executors.newFixedThreadPool(15); | ||
CountDownLatch latch = new CountDownLatch(totalCount); | ||
|
||
// 프로듀서 스레드 생성 | ||
for (int i = 0; i < totalCount; i++) { | ||
service.submit(() -> { | ||
try { | ||
producer.add(counteNumber); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
latch.countDown(); | ||
}); | ||
} | ||
// CounterCustomer 스레드 생성 및 비동기로 처리 시작 | ||
for(int i=0; i<3; i++){ | ||
CompletableFuture.runAsync(()->{ | ||
try{ | ||
consumer.consumeEvent(); | ||
} catch (InterruptedException e) { | ||
throw new RuntimeException(e); | ||
} | ||
}); | ||
} | ||
int finalCount = consumer.show(); | ||
LocalTime lt2 = LocalTime.now(); | ||
long dif = Duration.between(lt1, lt2).getNano(); | ||
logger.info("프로듀서_컨슈며_더하기_멀티_프로듀서_단일_컨슈머 테스트가 걸린 시간 : " + dif / 1000000 + "ms"); | ||
Assertions.assertEquals(initalCount + totalCount*counteNumber, finalCount); | ||
} | ||
} |
86 changes: 86 additions & 0 deletions
86
src/test/java/com/thread/concurrency/counter/SynchronizedCounterTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import com.thread.concurrency.AsyncServiceTest; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.DisplayName; | ||
import org.junit.jupiter.api.Test; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
import org.springframework.beans.factory.annotation.Autowired; | ||
import org.springframework.boot.test.context.SpringBootTest; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalTime; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import java.util.concurrent.*; | ||
|
||
@SpringBootTest | ||
public class SynchronizedCounterTest { | ||
|
||
private final int counteNumber = 1; | ||
private final int totalCount = 10000; | ||
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class); | ||
|
||
/** | ||
* 실행 완료까지 871ms 정도 소요 | ||
* @throws InterruptedException | ||
*/ | ||
@Test | ||
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기. 활동성 문제 예상") | ||
public void 여러_더하기_수행_Executor() throws InterruptedException { | ||
SynchronizedCounter counter = new SynchronizedCounter(); | ||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = counter.show(); | ||
int numberOfThreads = 15; | ||
ExecutorService service = Executors.newFixedThreadPool(15); | ||
CountDownLatch latch = new CountDownLatch(totalCount); | ||
for (int i = 0; i < totalCount; i++) { | ||
service.submit(() -> { | ||
counter.add(counteNumber); | ||
latch.countDown(); | ||
}); | ||
} | ||
latch.await(); | ||
int finalCount = counter.show(); | ||
LocalTime lt2 = LocalTime.now(); | ||
long dif = Duration.between(lt1, lt2).getNano(); | ||
logger.info("여러_더하기_수행_Executor 테스트가 걸린 시간 : "+dif/1000000+"ms"); | ||
Assertions.assertEquals(initalCount+totalCount*counteNumber, finalCount); | ||
} | ||
|
||
/** | ||
* 실행 완료까지 1061ms 소요 | ||
*/ | ||
@Test | ||
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기. 활동성 문제 예상") | ||
public void 여러_더하기_수행_CompletableFuture() { | ||
SynchronizedCounter counter = new SynchronizedCounter(); | ||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = counter.show(); | ||
List<CompletableFuture<Void>> tasks = new ArrayList<>(); | ||
for(int i=0; i<totalCount; i++){ | ||
tasks.add(CompletableFuture.runAsync(() -> counter.add(counteNumber))); | ||
} | ||
|
||
CompletableFuture<List<Void>> aggregate = CompletableFuture.completedFuture(new ArrayList<>()); | ||
for (CompletableFuture<Void> future : tasks) { | ||
aggregate = aggregate.thenCompose(list -> { | ||
try { | ||
list.add(future.get()); | ||
} catch (InterruptedException | ExecutionException e) { | ||
throw new RuntimeException(e); | ||
} | ||
return CompletableFuture.completedFuture(list); | ||
}); | ||
} | ||
aggregate.join(); // 전체 비동기 결과 집계 | ||
int finalCount = counter.show(); | ||
|
||
LocalTime lt2 = LocalTime.now(); | ||
long dif = Duration.between(lt1, lt2).getNano(); | ||
logger.info("여러_더하기_수행_CompletableFuture 테스트가 걸린 시간 : "+dif/1000000+"ms"); | ||
Assertions.assertEquals(initalCount+totalCount*counteNumber, finalCount); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
package com.thread.concurrency; |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.