Java 62

[java] bounded wildcard 표현

가끔 오픈소스 코드 보다보면 내부에 아래 같은 표현이 있어서 뭔가 싶었는데 이참에 정리해봤다. : Unbounded Wildcard : 어떤 타입이든 허용 (제한 없음) : Upper Bounded Wildcard : T 또는 T의 하위 타입 (상한 제한) : Lower Bounded Wildcard : T 또는 T의 상위 타입 (하한 제한) 기억하기 어려우면 PECS로 기억하면 된다. Producer extends / Consumer super 생산자는 extends를 쓰고, Consumer는 super를 쓴다 정도로, 아래 예시 보면 좀 이해가 도움이 될 듯 static void copy(List dest, List src) { for (T e : src) { // src는 값을..

Java 2025.07.27

[Java] ConcurrentModificationException 예외 해결 방법

오늘 Java로 MUD 게임을 개발하던 중 ConcurrentModificationException 이라는 예외를 만나게 되었다. 지금까지 개발하면서 이 예외를 처음 본 것 같다는 생각이 들었다 . 이전에 본 적이 있다면 조금이라도 기억이 날텐데 이 예외는 왠지 오늘 처음 발생한 예외라고 생각했다. 자료구조를 순회하면서 해서는 안되는 동작에 대해 알고 있다면 발생하지 않는 예외에 속한다. 왜 발생하는 지와 그 해결 방법에 대해서 간단하게 알아보고자 한다. 핵심은 간단하다. 자료구조를 순회하면서 우리는 특정 원소에 대해 Delete 연산을 수행하게 되는데 이때 자료구조를 for loop으로 순회하면서 .size() 혹은 len() 혹은 .legth를 통해 loop 횟수를 정해줬을 것이다. 그런데 순회하는 ..

Java 2022.12.08

[Java] 외부에서 스레드를 안전하게 종료하는 방법

프로젝트를 진행하면서 Thread를 활용해야 하는 작업을 진행하고 있었다. 그러면서 특정 조건에서 Thread를 죽여야만 하는 상황이 존재했는데 어떻게 하면 외부에서 Thread를 죽일 수 있는지에 대해 고민하고 있었다. Thread의 run 내부에서는 보통 while true를 활용해서 무한 루프를 돌기 마련인데 이걸 특정 Flag를 활용해서 while true 가 아니라 while !flag 와 같은 식으로 while 문을 돌면서 flag 를 검사해주는 방식으로 할 지에 대해 고민했다. 결국에는 외부에서 해당 Thread 내에 있는 boolean stop flag 변수에 접근해서 해당 변수의 값을 바꿔주었고 while로 무한 루프를 돌던 Thread는 해당 stop flag 값이 true가 되었음을 ..

Java 2022.11.30

[Java] 생성자에서는 getInstance호출에 신중하자.

오늘 코드를 작성하던 중 신기한 현상을 만났다. 게임 서버를 구동했는데 정상 작동하지 않았다. 신기하게도 아무런 에러도 찍히지 않았다. 분명 어딘가 문제가 있을 것이라고 생각하고 살펴보았지만 짐작가는 곳은 없어서 빠르게 해결하기 위해 출력문으로 찍어보고 문제의 핵심을 찾았다. 아래 두 코드 부분을 보자. 두 코드는 각각 Game과 RedisTemplate의 생성자에 관한 코드이다. 왼쪽에 존재하는 Game에서는 RedisTemplate의 객체를 getInstance를 통해 받아오려 하고 있다. 오른쪽의 RedisTemplate 또한 Game의 객체를 getInstance를 통해 받아오려 하고 있다. 참고로 Game와 RedisTemplate 모두 싱글톤으로 작성되어있다. 그렇다면 이렇게 생성자 내에서 서..

Java 2022.11.30

[Java] Java에서 Redis 를 사용해보자. Jedis 사용하기

Java에서 Redis 를 사용해보자. Java 에서 Redis 를 쓸 수 있도록 Jedis 가 이미 준비되어있다. Gradle 에는 다음과 같이 추가한다. // https://mvnrepository.com/artifact/redis.clients/jedis implementation group: 'redis.clients', name: 'jedis', version: '2.8.0' 이후 아래 코드와 같이 redisTemplate 을 작성할 수 있다. redisTemplate 이란 redis 의 기본적인 명령어들을 method를 호출함으로써 사용할 수 있게끔 래핑한 클래스라고 볼 수 있다. 아래 예시를 천천히 살펴보자. // redisTemplate 아래 블로그에서 많은 도움을 받았습니다. 감사합니다...

Java 2022.11.23

[Java] PrintWriter 의 AutoFlush 사용

TCP 상에서 Client와 Server 상에서 문자열을 주고받는 것을 확인하려고 하는 와중에 문제가 발생했다. 아무리 client에서 입력을 하고 readLine으로 읽어들인 문자열을 server 쪽으로 보내려고 해도 server 상에서 받았다는 표시가 뜨지 않았다. 즉 아예 받지 못한 문제가 발생했다. 컴파일이나 런타임 에러도 아니고 그저 의도된 작동이 재현되지 않는 것이 문제였다. 문제의 원인은 금방 찾을 수 있었다. 원인은 PrintWriter에서 AuthFlush 를 사용하지 않았기 때문이다. 이제 문제가 발생한 배경에 대해서 알아보도록 하겠다. 우리는 통상 TCP 소켓 프로그래밍을 할때 server 쪽으로 전송하기 위해 client에 다음과 같은 코드를 작성하게 된다. in = new Buff..

Java 2022.11.23

[Java] Java project Loom and Virtual Threads

최근 커뮤니티에서 많이 언급되는 주제가 있다. 바로 Java project Loom 의 Virtual Threads 이다. 최근 뜨거운 감자인데 어느 정도는 알아둬야겠다고 생각해서 간단하게 내용을 살펴보고자 한다. 우선 프로젝트 룸이란 무엇일까? The primary goal of Project Loom is to support a high-throughput, Lightweight concurrency model in java. 즉 자바의 동시성 모델에서 가벼우면서도 고성능을 지원할 수 있게 하는 프로젝트라고 볼 수 있다. OpenJDK에 의해서 시작되었다고 한다. Project Loom에 대해서 언급하기 이전에 먼저 자바의 동시성 모델에 대해 간략하게 알고 가는 것이 좋다. Thread는 다바의 동시..

Java 2022.11.16

[Java] 제너릭 메소드의 선언부에 대해

제너릭 메소드의 선언부에 대해 https://devlog-wjdrbs96.tistory.com/201 [Java] 제너릭 메소드(Generic Method)란? 제너릭 메소드 제네릭 메소드는 메소드의 선언 부에 적은 제네릭으로 리턴 타입, 파라미터의 타입이 정해지는 메소드이다. 제너릭에 대한 예시를 보면서 이해해보자. public class Student { static T nam devlog-wjdrbs96.tistory.com https://atoz-develop.tistory.com/entry/JAVA-%EC%A0%9C%EB%84%A4%EB%A6%ADGenerics-%ED%81%B4%EB%9E%98%EC%8A%A4%EC%99%80-%EB%A9%94%EC%86%8C%EB%93%9C JAVA 제네릭(G..

Java 2021.01.06

[Java] 유틸리티 클래스란 무엇인가?

유틸리티 클래스란 무엇인가? 어려운 개념은 없고 그냥 용어이다. 유틸리티 클래스는 인스턴스 메서드와 인스턴스 변수를 일절 제공하지 않고 정적 메서드와 변수만을 제공하는 클래스를 뜻한다. 클래스 본래의 목적인 '데이터와 데이터 처리를 위한 로직의 캡슐화' 를 실행하는 것이 아니라 '비슷한 기능의 메서드와 상수를 모아서 캡슐화' 한 것이 유틸리티 클래스이다. 설명이 너무 짧아서 static에 대해서 조금 더 언급하겠다. static을 사용하는 이유는 공유 때문이다. static 을 사용하면 새로 생성되는게 아니라 항상 같은 곳의 메모리 주소를 향하기 때문에 static 변수의 경우는 그 값이 공유가 가능하다. static method는 어떤 개념일까? static method는 메서드의 앞부분에 static..

Java 2021.01.06

[Java] 정적 팩토리 메서드란 무엇인가?

정적 팩토리 메서드란 무엇인가? https://johngrib.github.io/wiki/static-factory-method-pattern/ 정적 팩토리 메서드(static factory method) static 메서드로 객체 생성을 캡슐화한다 johngrib.github.io https://velog.io/@ljinsk3/%EC%A0%95%EC%A0%81-%ED%8C%A9%ED%86%A0%EB%A6%AC-%EB%A9%94%EC%84%9C%EB%93%9C%EB%8A%94-%EC%99%9C-%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C 정적 팩토리 메서드는 왜 사용할까? 정적 팩토리 메서드를 들어본 적이 있는가? 프로그래밍을 시작한 지 얼마 안된 사람도 정적 팩토리 메서드라는 단어..

Java 2021.01.06

[Java] 스레드에서 등장하는 원자성의 보장이란 무엇인가?

멀티 쓰레드(multi-thread) 기반의 프로그래밍을 하게 되면 중요한 것이 바로 원자성의 보장이다. 그렇다면 원자성이 무엇인가? 원자성이란 여러개의 쓰레드가 있을 때 특정 시점에 어떤 메소드를 두개 이상의 쓰레드가 동시에 호출 못한다는 것이다. 간단한 예를 들어보자. class Job implements Runnable { public void run() { while(true) { go(); stop(); } } public void go() { /* 매우 중요한 작업이다 */ } public void stop() { /* 그냥 일반적인 작업이다. */ } } 위의 Job 클래스를 보면 run()메소드에서 go()와 stop()메소드를 무한 호출하고 있다. 그런데 여기에서 go()메소드가 아주 중..

Java 2021.01.05

[Java] 공유객체와 volatile 키워드

공유객체란 무엇일까? 공유객체는 하나의 객체를 여러 개의 Thread가 사용한다는 의미이다. volatile은 무엇일까? volatile은 해당 키워드로 선언된 변수를 컴파일러의 최적화 대상에서 제외시킨다는 의미이다. 그래서 값이 변경되는 즉시 변수에 적용시킨다. 그런데 하나의 Thread가 아닌 여러 Thread가 Write하는 상황에서는 적합하지 않다고 한다. Java에서 volatile은 Java 변수를 Main Memory에 저장하겠다는 것을 명시하는 키워드이다. 그래서 변수의 값을 읽을때 CPU 캐시에 저장된 값이 아니라 Main Memory에서 읽게 되는 것이다. 그리고 마찬가지로 변수의 값을 쓸때도 Main Memory에까지 작성하는 것이다. 왜 volatile 키워드가 필요할까? volat..

Java 2021.01.05

[Java] 자바 System.out과 System.err의 차이

자바의 System.out 과 System.err 의 차이에 대해서 알아보자. 사실 별 차이가 없는 줄 알았는데 생각보다 흥미로운 차이가 있어서 정리하게 되었다. out과 err는 다른 타이밍에 flush를 한다는 것이 차이점이다. out스트림은 자체적으로 자신의 버퍼를 가지고 있다. 여러개의 print request를 버퍼에 넣고 기다렸다가 적절한 타이밍에 한번에 출력하는 것이다. 이렇게 하는 이유는 속도 때문이라고 한다. print구문이 있을때마다 바로 콘솔에 메시지를 flush해서 출력하면 JVM 성능 상에 영향을 주기 때문이라고 한다. err스트림도 자체적으로 자신의 버퍼를 가지고 있다고 한다. 하지만 err라는 것을 보면 알 수 있듯이 에러 상황과 같이 일반적이지 않은 상황에서의 출력을 의미하기..

Java 2021.01.05

[Java] 왜 자바에서는 static 사용을 지양해야 하는가?

왜 자바에서는 static의 사용을 지양해야 하는가에 대해서 알아보자. static 변수는 전역 상태이다. 그런데 global state는 추론과 테스트가 매우 까다롭다고 한다. 이 static 변수가 코드의 여러 부분에서 영향을 받을 수 있는데 이 변화를 모두 추적하기가 까다로운 셈이다. 그런데 이걸 객체화해서 인스턴스로 생성해서 사용하면 테스트 도중에 그 변수가 어떤 상태인지 알기 쉽기 때문에 인스턴스화가 좀 더 좋다고 한다. 결국에는 테스트 시에 추적이 어렵기 때문에 static을 자주 쓰지 말라는 것이다. 또한 static은 객체 지향적이지 않다고 한다. static 변수는 특히 캡슐화의 원칙에 위배된다고 한다. static이 scope를 고려할 필요없이 global하게 사용될 수 있기 때문에 절..

Java 2021.01.05

[이것이 자바다] 자바 정규표현식 공부 정리

pattern_match package sec10.exam01_pattern_match; import java.util.regex.Pattern; public class PatternExample { public static void main(String[] args) { String regExp = "(02|010)-\\d{3,4}-\\d{4}";// 자바에서는 역슬래쉬가 특정한의미가 있으므로 역슬래쉬가 역슬래쉬임을 알리기 위해 역슬래쉬를 두번 쓴다. String data = "010-123-4567";//사용자가 입력한 데이터라고 가정 boolean result = Pattern.matches(regExp, data); //정규표현식으로 data를 검정한다. if(result) { System.out..

Java 2021.01.05

[Java] 자바 ExecutorService와 Future에 대해서

codechacha.com/ko/java-executors/ Java - ExecutorService를 사용하는 방법 Executors와 ExecutorService를 이용하면 간단히 쓰레드풀을 생성하여 병렬처리를 할 수 있습니다. 어떤 작업들을 병렬로 처리하려면 ExecutorService, SingleThreadExecutor, Future, BlockingQueue를 이용해야 합니다. codechacha.com gunju-ko.github.io/java/2018/07/05/Future.html Java Future Future, CompletableFuture, ListenableFuture Future Future는 비동기 처리 결과를 표현하기 위해서 사용된다. 비동기 처리가 완료되었는지 확인하고..

Java 2021.01.04

[디자인패턴] 헤드퍼스트 디자인패턴 - 스트래티지 패턴

객체지향의 기초에는 추상화 캡슐화 다형성 상속 이 존재한다. 객체지향의 원칙에는 바뀌는 부분은 캡슐화한다. 상속보다는 구성을 활용한다. 구현이 아닌 인터페이스에 맞춰서 프로그래밍한다. 가 있다. 객체지향 패턴 중 스트레티지 패턴은 알고리즘군을 정의하고 각각을 캡슐화하여 바꿔 쓸 수 있게 만든다. 스트패티지 패턴을 이용하면 알고리즘을 활용하는 클라이언트와 독립적으로 알고리즘을 변경할 수 있다. 교재에서 활용한 예제는 다음과 같다. public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public Duck(){} public abstract void display(); public void performFly() ..

Java 2021.01.04

[Java] 자바 Map 종류와 좋은 블로그

자바 관련 좋은 블로그 소개 https://beomseok95.tistory.com/category/JAVA 자바 Map의 종류에 대해 (Hash, Tree, Linked) 그리고 해쉬테이블까지 https://web-inf.tistory.com/44 https://coding-factory.tistory.com/557 https://velog.io/@adam2/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0%ED%95%B4%EC%8B%9C-%ED%85%8C%EC%9D%B4%EB%B8%94 (위의 velog에는 해싱, 그리고 해쉬테이블에 대한 깊은 내용이 나와있다. ) https://wakestand.tistory.com/190 사실 위에 소개된 3개의 블로그 중에서 이 코딩팩토리라는 블..

Java 2021.01.04

[Java] 자바 헷갈리는 내용 - 접근제어자와 final 클래스와 메서드

접근제어자를 별도로 설정하지 않는다면 접근제어자가 없는 변수, 메소드는 default 접근제어자가 되어 해당 패키지 내에서만 접근이 가능하다. 접근제어자가 protected로 설정되었다면 protected가 붙은 변수, 메소드는 동일 패키지내의 클래스 또는 해당 클래스를 상속받은 외부 패키지의 클래스에서 접근이 가능하다. final 이라는 예약어가 붙은 클래스와 메소드는 상속과 오버라이드가 막히게 된다.

Java 2021.01.04

[Java] 자바8 함수형 인터페이스에 관한 자세한 설명

자바8 함수형 인터페이스에 관한 자세한 설명(상당히 자세하다...) https://beomseok95.tistory.com/277?category=1064782 Functional Interface는 Object 클래스의 메서드를 제외하고 단 하나의 메서드만 가지고 있는 인터페이스를 의미합니다 람다식은 기본적으로 "파라미 터부 -> {몸통부}"의 형태를 띠며 평가 결과로 Functional Interface의 인스턴스를 생성할 수 있습니다, Stream 인터페이스는 람다식과 결합하여 List를 일괄적으로 처리할 수 있도록 도와준다. 대표적인 메서드로 filter, map, forEach 등이 있다. 이 API를 이용하면..

Java 2021.01.04

[Java] Junit과 테스트 주도 개발(TDD) 그리고 리팩토링

Junit 공식 사이트 https://junit.org/junit5/ Junit이란? 자바의 단위 테스트 프레임워크 https://nesoy.github.io/articles/2017-02/JUnit http://www.nextree.co.kr/p11104/ http://junit.sourceforge.net/javadoc/org/junit/Assert.html Junit과 테스트 주도 개발 방법론 (TDD) https://galid1.tistory.com/329?category=763585 https://galid1.tistory.com/783?category=763585 TDD의 개념적 원칙 (FIRST 원칙 ) https://galid1.tistory.com/783?category=763585 TD..

Java 2021.01.04