Skip to content

Commit 35d3cbf

Browse files
authored
Integrated develop (#32)
## 개요 <!-- 이 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 -->
2 parents ed4626c + d7e8a86 commit 35d3cbf

File tree

6 files changed

+217
-0
lines changed

6 files changed

+217
-0
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.thread.concurrency.counter;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
import java.util.concurrent.atomic.AtomicInteger;
6+
7+
@Component
8+
public class AtomicCounter implements Counter{
9+
private final AtomicInteger count = new AtomicInteger(100);
10+
@Override
11+
public void add(int value) {
12+
count.addAndGet(value);
13+
}
14+
@Override
15+
public int show() {
16+
return count.get();
17+
}
18+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.thread.concurrency.counter;
2+
3+
import org.springframework.stereotype.Component;
4+
import java.util.concurrent.CompletableFuture;
5+
import java.util.concurrent.ExecutionException;
6+
7+
@Component
8+
public class CompletableFutureCounter implements Counter{
9+
10+
private CompletableFuture<Integer> counter;
11+
public CompletableFutureCounter(){
12+
this.counter = new CompletableFuture<>();
13+
counter.complete(100);
14+
}
15+
@Override
16+
public void add(int value) {
17+
synchronized (this){
18+
counter = counter.thenApply((c) -> c + value);
19+
}
20+
}
21+
@Override
22+
public int show() {
23+
try {
24+
return counter.get();
25+
} catch (InterruptedException | ExecutionException e) {
26+
throw new RuntimeException(e);
27+
}
28+
}
29+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.thread.concurrency.counter;
2+
3+
import org.springframework.stereotype.Component;
4+
5+
@Component
6+
public class SynchronizedCounter implements Counter{
7+
8+
private int counter = 100;
9+
10+
@Override
11+
public synchronized void add(int value) {
12+
counter += value;
13+
}
14+
15+
@Override
16+
public synchronized int show() {
17+
return counter;
18+
}
19+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.thread.concurrency;
2+
3+
import com.thread.concurrency.counter.AtomicCounter;
4+
import org.junit.jupiter.api.Assertions;
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.test.context.SpringBootTest;
11+
12+
import java.time.Duration;
13+
import java.time.LocalTime;
14+
import java.util.concurrent.CountDownLatch;
15+
import java.util.concurrent.ExecutorService;
16+
import java.util.concurrent.Executors;
17+
18+
@SpringBootTest
19+
public class AtomicCounterTest {
20+
private final int counteNumber = 1;
21+
private final int totalCount = 5000000;
22+
private final int maxThreadNumber = 15;
23+
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class);
24+
@Autowired
25+
AtomicCounter counter;
26+
27+
@Test
28+
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.")
29+
public void 여러_더하기_수행_Executor() throws InterruptedException {
30+
31+
LocalTime lt1 = LocalTime.now();
32+
int initalCount = counter.show();
33+
34+
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber);
35+
CountDownLatch latch = new CountDownLatch(totalCount);
36+
for (int i = 0; i < totalCount; i++) {
37+
service.submit(() -> {
38+
counter.add(counteNumber);
39+
latch.countDown();
40+
});
41+
}
42+
latch.await();
43+
int finalCount = counter.show();
44+
LocalTime lt2 = LocalTime.now();
45+
long dif = Duration.between(lt1, lt2).getNano();
46+
logger.info("여러_더하기_수행_Executor 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms");
47+
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount);
48+
}
49+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.thread.concurrency;
2+
3+
import com.thread.concurrency.counter.CompletableFutureCounter;
4+
import org.junit.jupiter.api.Assertions;
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.test.context.SpringBootTest;
11+
import org.springframework.context.annotation.Bean;
12+
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
13+
14+
import java.time.Duration;
15+
import java.time.LocalTime;
16+
import java.util.ArrayList;
17+
import java.util.List;
18+
import java.util.concurrent.*;
19+
20+
@SpringBootTest
21+
public class CompletableFutureCounterTest {
22+
23+
private final int counteNumber = 1;
24+
private final int totalCount = 5000;
25+
private final int maxThreadNumber = 15;
26+
private static final Logger logger = LoggerFactory.getLogger(CompletableFutureCounterTest.class);
27+
28+
@Autowired
29+
CompletableFutureCounter counter;
30+
@Test
31+
@DisplayName("CompletableFuture로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.")
32+
public void 여러_더하기_수행_Executor() throws InterruptedException {
33+
LocalTime lt1 = LocalTime.now();
34+
int initalCount = counter.show();
35+
36+
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber);
37+
CountDownLatch latch = new CountDownLatch(totalCount);
38+
for (int i = 0; i < totalCount; i++) {
39+
service.submit(() -> {
40+
counter.add(counteNumber);
41+
latch.countDown();
42+
});
43+
}
44+
latch.await();
45+
int finalCount = counter.show();
46+
LocalTime lt2 = LocalTime.now();
47+
long dif = Duration.between(lt1, lt2).getNano();
48+
logger.info("여러_더하기_수행_Executor 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms");
49+
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount);
50+
}
51+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.thread.concurrency;
2+
3+
import com.thread.concurrency.counter.SynchronizedCounter;
4+
import org.junit.jupiter.api.Assertions;
5+
import org.junit.jupiter.api.DisplayName;
6+
import org.junit.jupiter.api.Test;
7+
import org.slf4j.Logger;
8+
import org.slf4j.LoggerFactory;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.test.context.SpringBootTest;
11+
12+
import java.time.Duration;
13+
import java.time.LocalTime;
14+
import java.util.concurrent.CountDownLatch;
15+
import java.util.concurrent.ExecutorService;
16+
import java.util.concurrent.Executors;
17+
18+
@SpringBootTest
19+
public class SynchronizedCounterTest {
20+
21+
private final int counteNumber = 1;
22+
private final int totalCount = 5000000;
23+
private final int maxThreadNumber = 15;
24+
private static final Logger logger = LoggerFactory.getLogger(SynchronizedCounterTest.class);
25+
26+
@Autowired
27+
SynchronizedCounter counter;
28+
29+
@Test
30+
@DisplayName("synchronized로 스레드 안전한 카운터로 동시에 여러 더하기 수행하기.")
31+
public void 여러_더하기_수행_Executor() throws InterruptedException {
32+
33+
LocalTime lt1 = LocalTime.now();
34+
int initalCount = counter.show();
35+
36+
ExecutorService service = Executors.newFixedThreadPool(maxThreadNumber);
37+
CountDownLatch latch = new CountDownLatch(totalCount);
38+
for (int i = 0; i < totalCount; i++) {
39+
service.submit(() -> {
40+
counter.add(counteNumber);
41+
latch.countDown();
42+
});
43+
}
44+
latch.await();
45+
int finalCount = counter.show();
46+
LocalTime lt2 = LocalTime.now();
47+
long dif = Duration.between(lt1, lt2).getNano();
48+
logger.info("여러_더하기_수행_Executor 테스트가 걸린 시간 : " + ((float)dif / 1000000) + "ms");
49+
Assertions.assertEquals(initalCount + totalCount * counteNumber, finalCount);
50+
}
51+
}

0 commit comments

Comments
 (0)