Skip to content

Commit

Permalink
Integrated develop (#32)
Browse files Browse the repository at this point in the history
## 개요

<!-- 이 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
ooMia authored Apr 3, 2024
2 parents ed4626c + d7e8a86 commit 35d3cbf
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/main/java/com/thread/concurrency/counter/AtomicCounter.java
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();
}
}
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);

Check warning on line 26 in src/main/java/com/thread/concurrency/counter/CompletableFutureCounter.java

View check run for this annotation

Codecov / codecov/patch

src/main/java/com/thread/concurrency/counter/CompletableFutureCounter.java#L25-L26

Added lines #L25 - L26 were not covered by tests
}
}
}
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 src/test/java/com/thread/concurrency/AtomicCounterTest.java
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);
}
}
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 src/test/java/com/thread/concurrency/SynchronizedCounterTest.java
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);
}
}

0 comments on commit 35d3cbf

Please sign in to comment.