-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## 개요 <!-- 이 PR은 무엇을 하는지 간단히 설명해주세요. - 새로운 로그인 기능 추가 --> 1. AtomicInteger를 이용한 카운터 2. CompletableFuture를 이용한 카운터 3. Synchronized를 이용한 카운터 ## 변경 사항 <!-- 이 PR로 인해 어떤 것이 변경되는지 나열해주세요. - [x] 🐛 Fix : 오류 수정 - [x] ✨ Feat : 새로운 기능 - [x] 🔧 Modify : 위치 변경 - [x] 🤖 Refactor : 코드 리팩토링 - [x] ✅ Test : 테스트 코드 추가 - [x] 💡 Comment : 필요한 주석 추가 및 변경 - [x] 🚚 Chore : 환경설정 변경 - [x] 🎨 Style : 의미 없는 코드 형식 수정 - [x] 🔥 Remove : 삭제 - [x] 📝 Docs : 문서 수정 --> ✨ Feat : 새로운 기 ✅ Test : 테스트 코드 추가 ## 추가 정보 <!-- 이 PR에 대해 필요한 후속 작업이 있다면 추가해주세요. - [ ] 로그인 페이지 추가 필요 - [ ] 로그인 API 연결 필요 --> - [ ] 각 카운터데 대해서 수행시간과 메모리 사용량을 테이블 형식으로 Readme에 작성 ### 관련 이슈 <!-- 문제를 해결한다면 Fix 또는 Resolve 일반적으로는 Closes #123 -->
- Loading branch information
Showing
6 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
18 changes: 18 additions & 0 deletions
18
src/main/java/com/thread/concurrency/counter/AtomicCounter.java
This file contains 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.counter; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
@Component | ||
public class AtomicCounter implements Counter{ | ||
private final AtomicInteger count = new AtomicInteger(100); | ||
@Override | ||
public void add(int value) { | ||
count.addAndGet(value); | ||
} | ||
@Override | ||
public int show() { | ||
return count.get(); | ||
} | ||
} |
29 changes: 29 additions & 0 deletions
29
src/main/java/com/thread/concurrency/counter/CompletableFutureCounter.java
This file contains 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,29 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import org.springframework.stereotype.Component; | ||
import java.util.concurrent.CompletableFuture; | ||
import java.util.concurrent.ExecutionException; | ||
|
||
@Component | ||
public class CompletableFutureCounter implements Counter{ | ||
|
||
private CompletableFuture<Integer> counter; | ||
public CompletableFutureCounter(){ | ||
this.counter = new CompletableFuture<>(); | ||
counter.complete(100); | ||
} | ||
@Override | ||
public void add(int value) { | ||
synchronized (this){ | ||
counter = counter.thenApply((c) -> c + value); | ||
} | ||
} | ||
@Override | ||
public int show() { | ||
try { | ||
return counter.get(); | ||
} catch (InterruptedException | ExecutionException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
src/main/java/com/thread/concurrency/counter/SynchronizedCounter.java
This file contains 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,19 @@ | ||
package com.thread.concurrency.counter; | ||
|
||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class SynchronizedCounter implements Counter{ | ||
|
||
private int counter = 100; | ||
|
||
@Override | ||
public synchronized void add(int value) { | ||
counter += value; | ||
} | ||
|
||
@Override | ||
public synchronized int show() { | ||
return counter; | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
src/test/java/com/thread/concurrency/AtomicCounterTest.java
This file contains 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,49 @@ | ||
package com.thread.concurrency; | ||
|
||
import com.thread.concurrency.counter.AtomicCounter; | ||
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.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
@SpringBootTest | ||
public class AtomicCounterTest { | ||
private final int counteNumber = 1; | ||
private final int totalCount = 5000000; | ||
private final int maxThreadNumber = 15; | ||
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class); | ||
@Autowired | ||
AtomicCounter counter; | ||
|
||
@Test | ||
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.") | ||
public void 여러_더하기_수행_Executor() throws InterruptedException { | ||
|
||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = counter.show(); | ||
|
||
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber); | ||
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 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms"); | ||
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/test/java/com/thread/concurrency/CompletableFutureCounterTest.java
This file contains 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,51 @@ | ||
package com.thread.concurrency; | ||
|
||
import com.thread.concurrency.counter.CompletableFutureCounter; | ||
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 org.springframework.context.annotation.Bean; | ||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; | ||
|
||
import java.time.Duration; | ||
import java.time.LocalTime; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.concurrent.*; | ||
|
||
@SpringBootTest | ||
public class CompletableFutureCounterTest { | ||
|
||
private final int counteNumber = 1; | ||
private final int totalCount = 5000; | ||
private final int maxThreadNumber = 15; | ||
private static final Logger logger = LoggerFactory.getLogger(CompletableFutureCounterTest.class); | ||
|
||
@Autowired | ||
CompletableFutureCounter counter; | ||
@Test | ||
@DisplayName("CompletableFuture로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.") | ||
public void 여러_더하기_수행_Executor() throws InterruptedException { | ||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = counter.show(); | ||
|
||
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber); | ||
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 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms"); | ||
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
src/test/java/com/thread/concurrency/SynchronizedCounterTest.java
This file contains 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,51 @@ | ||
package com.thread.concurrency; | ||
|
||
import com.thread.concurrency.counter.SynchronizedCounter; | ||
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.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
|
||
@SpringBootTest | ||
public class SynchronizedCounterTest { | ||
|
||
private final int counteNumber = 1; | ||
private final int totalCount = 5000000; | ||
private final int maxThreadNumber = 15; | ||
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class); | ||
|
||
@Autowired | ||
SynchronizedCounter counter; | ||
|
||
@Test | ||
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.") | ||
public void 여러_더하기_수행_Executor() throws InterruptedException { | ||
|
||
LocalTime lt1 = LocalTime.now(); | ||
int initalCount = counter.show(); | ||
|
||
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber); | ||
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 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms"); | ||
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount); | ||
} | ||
} |