클린 코드에 null을 리턴하지 말라는 얘기가 있다.

동감이다. null만 검사하다가 코드는 지저분하게 끝나고 만다.


Collections 클래스에 있는 비어있는 객체를 활용한다. list, map, set 종류별로 다 있다.

다만 static final이기 때문에 리턴받은 후에 추가를 하려고 하면 에러가 나기 때문에 쓰임새에 유의해야 한다.

java.util.Collections

  • static <T> Enumeration<T> emptyEnumeration()
  • static <T> Iterator<T> emptyIterator()
  • static <T> List<T> emptyList()
  • static <T> ListIterator<T> emptyListIterator()
  • static <K,V> Map<K,V> emptyMap()
  • static <T> Set<T> emptySet()


String 리턴의 경우 null을 어떻게 해야 할까 고민해 보았는데

common의 StringUtils.EMPTY에 static final로 공백 String이 들어가 있어서 사용해 볼 수 있다.

아쉽게도 spring의 StringUtils에는 EMPTY가 없었다.


org.apache.commons.lang.StringUtils

  • static String EMPTY




신고

Leave a Comment

Could not fetch model of type 'EclipseProject' using Gradle distribution

Could not fetch model of type 'EclipseProject' using Gradle distribution " http://services.gradle.org/distributions/gradle-1.10-bin.zip"

나는 현재 신규 프로젝트를 Gradle로 빌드하고 있다.

이클립스는 STS를 사용중인데, 다른 프로젝트를 임포트하고 신규 프로젝트를 생성하는 과정에서 JBoss가 필요하여 마켓에서 JBoss 플러그인을 설치하였다.


그런데 이전 프로젝트의 Gradle 빌드를 실행하려고 하니 위와 같은 에러가 발생하였다.


자세한 에러도 안 나오고, 네이버는 당연히 안 나오고 Google에서 검색하니 그나마 비슷한 사항이 나오기는 하나 해결책은 나오지 않는다. 맨붕이 오고 어떻게 해결할지는 모르겠고 자세한 로그도 없고

정말 STS 재설치해서 할까 고민했다.


고민 중에 아무래도 이클립스 플러그인 설치 후에 발생했다는 점과 오류 내용이 이클립스에서 Gradle 툴과 연관이 있지 않을까 싶었다.


그래서 마켓에서 내가 사용중이던 "Gradle IDE Pack"을 업데이트 해주었다.


다행히 문제 해결!!!!!!


같은 문제를 겪는 사람이 있다면 도움이 되길 바란다.

휴우..





신고

Leave a Comment

배포파일에 대하여 버전을 확인할 수 있게 해달라는 요청이 있었다.

파일명 뒤에 버전 붙이는 시덥잖은 방법으로는 한계가 있다.

하지만 java의 배포파일에 버전을 넣는 방법은 없다. 내가 모르는 것인가?

그리하여 JAR나 WAR에 공통적으로 들어가는 MANIFEST.MF 파일에 버전을 넣기로 했다.


해당 프로젝트는 Ant로 빌드하기 때문에 ant에 설정값을 추가했다.


<manifest file="MANIFEST.MF">

<attribute name="Manifest-Version" value="4.2013.2" />

</manifest>

<war ... manifest="MANIFEST.MF">

<jar ... manifest="MANIFEST.MF">


JAR나 WAR나 마찬가지이다.


그리고 저 파일을 확인할 수 있게 하기 위하여 bat파일과 sh파일을 만들었다.


check_version.bat

@echo off

if "%1" == "" goto HELP

jar xf %1 META-INF/MANIFEST.MF

TYPE META-INF\MANIFEST.MF

DEL META-INF\MANIFEST.MF

RMDIR META-INF\

goto QUIT


:HELP

echo ERROR: Missing JAR OR WAR file name

echo Usage: check_version.sh $war or jar filename

:QUIT



check_version.sh

#!/bin/ksh


if [ "$1" == "" ]; then

        echo "ERROR: Missing JAR OR WAR file name"

        echo "Usage: check_version.sh $war or jar filename"

        exit

fi


jar xf $1 META-INF/MANIFEST.MF

cat META-INF/MANIFEST.MF

rm META-INF/MANIFEST.MF

rm -r META-INF/




Reference

[1] Ant로 Manifest 설정 ( http://blog.naver.com/PostView.nhn?blogId=taekiblue&logNo=150033090682 )

신고

Leave a Comment

혹시 Java로 TCP서버를 구축하고 계신가요?

JAVA NIO를 공부하면서 서버 설계에 고민하고 계신가요?


서버 코어 설계 및 개발에 투자할 많은 시간 있다면? 그리고 안정성을 높이고 성능을 높이 끌어낼 자신과 시간이 있다면 직접 개발하세요. 하지만 그렇지 않다면 검증된 Java Network Framework인 Netty나 MINA를 사용해보세요.


이렇게 쓰니 제가 홍보하는 사람 같군요.

하지만 저의 경험입니다. 서버 코어 부분을 설계하고 개발하다보면 프로젝트에서 너무 많은 시간을 할애하게 되어버립니다. 그 후에 안정성이나 성능에 대해서도 고민이 되고 제가 나가면서 다른 사람에게 인수인계 할 때의 유지보수도 문제가 되어 버립니다.


그런 면에서 Netty나 MINA를 추천합니다.

사실 저도 어떻게 더 좋은지 모르겠습니다. 파운더이신 이희승씨가 Netty 사용을 권고하고 성능면에서도 Netty가 훌륭하다고 나왔지만, 역사가 길고 사용자가 많고 MINA를 사용해야 할지요. (어떤 분은 Netty 쓰지 말고 MINA를 써야 성능이 좋다고 하는 분도 있습니다.)


저는 netty를 사용합니다만 둘 다 우수한 프레임워크이니 골라서 사용해보시길 바랍니다.

두 개 모두 한국인 이희승씨가 개발하셨습니다. (아래 인터뷰를 읽어보면 이해가 잘 가실겁니다.)




Netty (JBoss)

자바 네트워크 어플리케이션 프레임워크

  • 이벤트 기반이며 비동기 방식
  • Interceptor Chain 패턴 방식
  • Old, New I/O 지원
  • NIO구현 벤더별 최적화
  • 과부하 및 Dos 방어 매커니즘 포함
  • 제한된 환경 지원(Android, Applet, WebStart)
  • 다양한 컨터이너 지원(JbossMc, OSGi, Guice, Spring)



1. 네티 공식 사이트

( http://netty.io/ )


2. netty  한국인 사용자 그룹

( http://groups.google.co.kr/group/netty-ko?hl=ko )


3. Netty, MINA 개발자 이희승님 인터뷰

http://www.bloter.net/archives/11472 )


4. 한국 미나 사용자께 드리는 네티로의 전환 권고

http://gleamynode.net/articles/2223/ )


6. Performance Comparison between NIO Frameworks

http://gleamynode.net/articles/2232/ )


7. Netty 사용에 관한 몇 가지 TIP

http://blog.pointbre.com/351/netty-%EC%82%AC%EC%9A%A9%EC%97%90-%EA%B4%80%ED%95%9C-%EB%AA%87%EA%B0%80%EC%A7%80-tip.html )


8. Netty User Guide

http://docs.jboss.org/netty/3.2/guide/html_single/ )


9. Netty Zero copy

http://clotho95.blog.me/140117229649 )


10. DEV 2012 Netty Internal Session

http://deview.kr/2012/xe/?mid=track&document_srl=379 )


11. Netty Tutorial

http://seeallhearall.blogspot.de/2012/05/netty-tutorial-part-1-introduction-to.html )






Apache MINA

MINA는 네트워크 어플리케이션 프로그래밍에 대한 지식 없이도 고성능 네트워크 어플리케이션을

쉽게 작성할 수 있도록 돕는 프레임워크


MINA 의 특징

  • TCP, UDP 트랜스포트 타입을 모두 지원
  • ByteBuffer 단위의 low-level I/O layer 와 Message object 단위의 high-level protocol layer를 모두 지원
  • Servlet filter 와 유사한 이벤트 필터링 기능을 제공하여 실시간 퍼포먼스 모니터링 및 이벤트 transformation (e.g. SSL 지원, 권한 검사, 클라이언트 블랙리스팅...) 가능
  • 같은 VM 내에 있는 MINA 어플리케이션 간의 통신시 in-VM pipe 를 제공하여 전문의 encode/decode 없이 바로 전달하여 성능을 극대화할 수 있음.


1. MINA
( http://mina.apache.org/ )


2. Javadoc

( http://mina.apache.org/mina-project/apidocs/index.html )


3. 특징

( http://mina.apache.org/mina-project/features.html )


4. Quick start

( http://mina.apache.org/mina-project/quick-start-guide.html )


5. Apache MINA Group

( http://mina.apache.org/mina-project/testimonials.html )


6. Download

( http://mina.apache.org/mina-project/downloads.html )


7. MINA 를 소개합니다. (차세대 Netty) by 이희승 (2004)

( http://www.javaservice.co.kr/~java/bbs/read.cgi?b=news&c=r_p&m=resource&n=1104313609&p=13&s=t )


8. MINA 강좌

http://mckdh.net/130 )






Netty vs MINA

1. MINA vs Netty

http://ellieya.tistory.com/23 )


2. Netty vs Apache MINA stackoverflow

( http://stackoverflow.com/questions/1637752/netty-vs-apache-mina )







신고

Leave a Comment

1. JBoss 설치

다양한 WAS중에서 나는 JBoss를 좋아한다. 회사에서는 주로 5버전을 쓰고 있었는데 최신 버전인 7 버전을 써보았다. 제일 좋은 점은 WAS 구동속도가 엄청나게 향상되었다.


Download URL : http://www.jboss.org/projects


* Admin 계정 생성

jboss-as-7.1.1.Final\bin>add-user.bat


* Server 시작

jboss-as-7.1.1.Final\bin>standalone.bat

$JBOSS_HOME/bin/standalone.sh


2. JBoss 환경변수 설정

linux) export JBOSS_HOME=/home/atin84/work/jboss-as-7.1.1.Final

win) 환경변수 JBOSS_HOME 추가


3. JBoss Admin 생성

JBoss 관리자 창에 접속하거나 Maven과 연동하기 위해서는 관리자 계정을 생성해주어야 한다.

$JBOSS_HOME/bin/add-user.sh

 What type of user do you wish to add?
 a) Management User (mgmt-users.properties)
 b) Application User (application-users.properties)
(a): a

Enter the details of the new user to add.
Realm (ManagementRealm) :
Username : atin84
Password :
Re-enter Password :
About to add user 'rocksea' for realm 'ManagementRealm'
Is this correct yes/no? yes
Added user 'rocksea' to file '$JBOSS_HOME/standalone/configuration/mgmt-users.properties'
Added user 'rocksea' to file '$JBOSS_HOME/domain/configuration/mgmt-users.properties'




4. JBoss Eclipse 플러그인

이클립스에서 기본 지원하는 JBoss 버전은 5에서 멈춰있다. 플러그인을 설치하자.

이클립스 상단메뉴의 Help>Install New Softwares


URL : http://download.jboss.org/jbosstools/updates/development/indigo/


JBoss Tool을 선택해서 설치하면 된다.


5. Maven 개발 환경시 배포

pom.xml에 다음과 같이 설정해준다. 자신의 pom.xml에 맞춰서 추가해주자.

<dependency>
        <groupId>maven</groupId>
        <artifactId>maven-jboss-plugin</artifactId>
        <version>1.5</version>
        <type>plugin</type>
</dependency>

<build>
     <plugins>
             <plugin>
                     <groupId>org.jboss.as.plugins</groupId>
                     <artifactId>jboss-as-maven-plugin</artifactId>
                     <version>7.3.Final</version>
             </plugin>
     </plugins>
</build> 


JBoss를 구동시켜준다. 일반적으로는 war를 배포하고 was를 재기동시켜줘야 하지만 이 방법은 was의 재기동 없이 배포를 해준다.


실행은 다음과 같이 해준다.

 $ mvn jboss-as:deploy


이클립스 환경에서는 실행 goal을 다음과 같이 해준다.

mvn jboss-as:deploy


그리고 웹 페이지에 접속해서 결과를 확인한다.



Reference

[1] JBoss 설치 (http://blog.whitelife.co.kr/entry/jBoss7-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0)

[2] JBoss 플러그인 설치 (http://jangnandev.blogspot.kr/2012/01/eclipse-indigo-jbossas7.html)

[3] Maven + JBoss 설치 및 배포 (http://rocksea.tistory.com/146)



신고

Leave a Comment

Maven & JBoss 개발 환경 구축

 1. Maven 설치

 2. Eclipse Maven Plug-in 설치

 3. JBoss 설치

 4. JBoss Eclipse Plug-in 설치

 5. 


1. Maven 다운로드

URL : http://maven.apache.org/download.cgi

환경변수 설정

MAVEN_HOME=C:\maven\apache-maven-3.0.3 (자신이 설치한 위치로)

path=%MAVEN_HOME%\bin


2. 이클립스 Maven 플러그인

이클립스 상단메뉴의 Help>Install New Softwares


2.1. m2e

http://m2eclipse.sonatype.org/sites/m2e


2.2. m2eclipse Extras

http://m2eclipse.sonatype.org/sites/m2e-extras


3. Maven 프로젝트 생성

콘솔에서 명령어를 쳐서 생성하는 방법이 있지만 별로 좋지 않다. 이클립스 Maven 프로젝트를 통해 생성하자.

신규 프로젝트 생성을 하다보면 메이븐 프로젝트 형태를 지정하는 것이 있는데 나는 jar 타입 프로젝트는 maven-archetype-quick-start로 하고 war타입 프로젝트는 maven-archetype-webapp 형태로 해서 생성을 하였다.


주의할 점이 있는데 프로젝트가 생성된 이후에 디렉토리 형태를 자기 입맛에 맞춰 변경하면 나중에 대참사가 발생한다. 나는 내가 개발하던 디렉토리 구조로 하고 싶어서 이것저것 변경하였는데 pom.xml에서 바꾼 디렉토리 구조를 하나하나 지정해주어야 하여만 하는것이었다. 그렇지 않으면 제대로 maven 실행을 할 수가 없다. 그런데 이 자기 입맛에 맞춰 pom.xml에 상세하게 지정해주는 것은 Maven 초보에게는 힘든 일이다. 덕분에 많이 배웠지만 가능하면 처음 생성된 디렉토리 구조대로 하는 것이 정신건강에 좋을 것이다. 또한 이 기본 디렉토리 구조를 많은 오픈소스에서 그대로 사용하고 있다.


4. Maven 빌드

내가 Maven을 사용하면서 가장 당황한 점은 빌드이다. 내가 Maven을 사용하면서 가장 큰 착각을 한 것은 Maven이 단순히 라이브러리를 관리해주는 툴 정도로 생각했던 점이다. 그러나 Maven의 기능은 그 이상으로 방대했다.

우선 Maven을 사용하면 ant를 사용할 필요가 없다. Maven에는 빌드, 단위테스트, 배포 등의 모든 기능이 포함되어 있다. 그리고 ant처럼 일일히 스크립트를 만들 필요도 없다. 정형화되어있는 goal을 실행함으로서 모든 작업을 한번에 수행할 수 있다.


Maven에서 가장 중요한 것은 pom.xml이다. 여기에 모든 Maven 설정이 들어가 있다.

만약 pom.xml을 클릭했을 때 xml만 나온다면 xml에 오른쪽 버튼을 누르고 open with에 Maven POM Editor을 선택하면 좀 더 편리하게 pom.xml을 관리할 수 있다.


이번 포스팅은 여기까지만 하고 다음에 goal, 그리고 내가 실수했던 빌드 설정들에 대해서 포스팅하도록 하겠다.



Reference

[1] Maven 설치1 (http://blog.whitelife.co.kr/entry/jBoss7-%EC%84%A4%EC%B9%98%ED%95%98%EA%B8%B0

http://blog.naver.com/PostView.nhn?blogId=seban21&logNo=70110678014)

[2] Maven 설치2 (http://blog.naver.com/PostView.nhn?blogId=seban21&logNo=70110678014)

[3] Maven 사용법 (http://maven.apache.org/plugins/maven-war-plugin/usage.html)


신고

Leave a Comment

http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-419409.html#jre-6u18-oth-JPR


막상 오라클 가서 찾으려고 하니 이전 마이너 버전을 찾기가 쉽지가 않다.

오라클 홈페이지에서 제공하고 있는데도 불구하고 말이다. 찾기 힘들어서 최신 버전만 올려두었나 싶었을 정도였다.



신고

Leave a Comment

Java 실행

1. Java 실행법

java CLASS_FILE_NAME

javaw CLASS_FILE_NAME


bat 파일에서 자바를 실행할 경우 콘솔창이 남게 된다.
이 경우에 콘솔창을 프로그램 실행 후 사라지게 하고 싶다면 도스 명령어 start를 쓰면 된다.

-사용법 (bat 파일에서)-
  start javaw 클래스명


2. 데몬 형태 실행 (리눅스)

자바 서버를 돌릴 때 주로 하며 백그라운드로 돌리게 된다.

nohup 실행명령어 1>/dev/null 2>&1 &


위에 명령어에 대한 설명이 궁금하다면 [1]을 참조


3. 데몬의 중지 (리눅스)

  1. ps -ef | grep java 와 같은 형태로 실행한 프로세스의 PID를 찾는다.

  2. kill -9 JAVA_PID


4. 로그 파일 모니터링 (리눅스)

 tail 명령어를 사용한다.

 ex) tail -f nohup.out


5. 실행파일 만들기

  4.1. Linux

    4.1.1. sh 파일 생성

      vi로 sh 파일을 생성하고 그 안에 실행 명령어를 적으면 된다. 외부에서 실행시에는 경로/test.sh 형태

    4.1.2. .bash_profile에 등록

        ex) alias psj='ps -ef|grep java'


  4.2. Windows

    bat파일을 생성하고 실행 명령어를 기입




Reference

[1] Linux에서 Java 실행법 ( http://blog.naver.com/PostView.nhn?blogId=typeofb&logNo=173589212 )

신고

Leave a Comment

쓰레드풀에서 생기는 메모리 릭 분석을 하다보니 또 포스팅하게 되었다.

생각해보면 학부 이후 Java 개발을 시작한 2008년도부터 늘 걱정되는 부분이다. JVM 덕분에 메모리 관리를 하지 않아도 되서 자바가 편하지만, 반대로 메모리 문제가 생기면 정말 짜증나게 하는 것이 또 자바이다.


 가끔은 내가 왜 C/C++만을 하지 않았을까 하는 후회가 들 때도 있다. C/C++을 이용하여 Visual Studio에서 개발하는 것이 그립기도 하고 순수 MFC 개발자가 부러울 때가 종종 있다. 잡설은 집어치우겠다..



메모리 릭 현상을 분석하다가 로그의 한계가 드러났다.

자세하게 분석을 해봐야겠다고 판단하였고 다시 한번 Eclipse MAT(http://www.eclipse.org/mat/)을 사용해봐야겠다고 판단되었다. Eclipse MAT은 Java Head Dump의 분석 툴로서 무료 소프트웨어 중에서는 제일 좋다고 여겨진다. 아쉽게도 잘 나와있는 설명서를 찾을 수가 없어서 사용해보면서 종종 익히는 중이다.


Eclipse MAT을 처음 사용해 본 것은 안드로이드 앱을 개발할 당시에 죽는 문제를 해결하기 위해서였다. 웹에서도 쓰이는지 몰랐는데, 톰캣의 Head Dump를 떠서 분석을 할 수 있었다.


[1]을 참고해서 톰캣에 Head Dump를 생성하였다.


Tomcat Memory Dump 생성 명령어

jmap -dump:format=b,file=파일명 톰캣PID


Tomcat PID 분석법

1. jps-v

2. tasklist /FI "WINDOWTITLE eq Tomcat"



[그림1. Tomcat PID 확인법]



[그림2. Tomcat Memory Dump 생성]



Memory Dump파일을 생성했다면, 그 이후로는 Eclipse MAT을 실행시켜서 덤프 파일을 분석하면 된다.



[그림3. Eclipse MAT에서 Memory Dump 파일 분석]






Reference

[1] RayG (http://rayg.tistory.com/49)




신고

Leave a Comment

Apache Tomcat6에서 구동하던 웹 애플리케이션에서 다음과 같은 에러를 발견하였다.


심각: The web application [/ AP_NAME ] registered the JDBC driver [com.mysql.jdbc.Driver] but failed to unregister it when the web application was stopped. To prevent a memory leak, the JDBC Driver has been forcibly unregistered.

2012. 7. 12 오후 1:58:59 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

심각: The web application [/ AP_NAME ] appears to have started a thread named [MySQL Statement Cancellation Timer] but has failed to stop it. This is very likely to create a memory leak.

2012. 7. 12 오후 1:58:59 org.apache.catalina.loader.WebappClassLoader clearReferencesThreads

심각: The web application [/AP_NAME] appears to have started a thread named [pool-1-thread-3] but has failed to stop it. This is very likely to create a memory leak.


이 에러는 톰캣을 시작하거나 종료할 때는 발생하지 않는다.

오직 톰캣을 완벽하게 내리지 않고, 해당 애플리케이션을 재시작하였을 때에만 발생한다. 

운영에 문제는 없다. 그러나 발견한 에러를 그냥 두는 것은 상당히 찜찜한 일이다. 그러므로 오늘 해결을 위해 조사 및 테스트를 해보았다.


위에서는 3개의 에러가 났다. JDBC와 관련되어서 2개가 발생하였고, 세번째는 ThreadPool에서 관리하는 쓰레드를 중지하지 못해서 난 것이다. 톰캣에서 발생한 이 메모리 누수의 발생 이유는 김용환 블로그[1]에 잘 나와 있었다.

그 이유는 다음과 같다.



     Mark는 이 OOME가 발생하는 원인을 톰캣이 아닌 Jvm, library라고 언급하였고, 그 예를 적었습니다.

(1)   Application, Library code 에 의해서 발생

A.     JDBC driver

B.      Logging framework

C.      ThreadLocal object를 저장하고 remove하지 않아서

D.     쓰레드를 시작시키고 멈추지 않아서

(2)   Java Api에 의해서도 발생

A.     Using the javax.imageio API (the Google Web Toolkit can trigger this)

B.      Using java.beans.Introspector.flushCaches()

        (Tomcat does this to prevent memory leaks caused by this caching)

C.      Using XML parsing (the root cause is unknown due to a bug in the JRE)

D.     Using RMI (somewhat ironically, causes a leak related to the garbage collector)

E.      Reading resources from JAR files

 

김용환 블로그[1]에서 발췌.



내가 얻은 3개의 에러도 위의 내요에 포함한다. A JDBC Driver와 D. 쓰레드를 시작시키고 멈추지 않아서이다.


우선 A를 해결하는 방법은 다음에 설명하겠다.(아직 여기까지는 하지 못했다.)


"D. 쓰레드를 시작시키고 멈추지 않아서"로 발생한 에러를 해결하는 방법에 대해서 써보겠다.



.



우선 Java에서 쓰레드에 대해 얘기해보자.

Java에서 쓰레드는 Thread클래스를 상속 받거나 Runnable 인터페이스를 구현해서 만들어진다. 그리고 Thread클래스의 start()메소드를 통해 시작하고 stop()메소드를 통해 중지되어진다.


그러나 한 두개의 쓰레드를 쓸 경우가 아니라면, 쓰레드를 관리하기 위해서 ThreadPool을 사용한다.(비단 java뿐만 아니라.)


내가 얻은 문제는 이 ThreadPool을 사용하면서 발생하였다.

난 웹 애플리케이션의 종료시에 ThreadPool에서 관리하는 쓰레드들을 shutdownNow메소드를 이용하여 중지시켰다. 그러나 shutdownNow메소드는 내부에서 관리되는 쓰레드들을 중지시키지 못했다.


왜일까?


우선 Thread의 stop메소드와 ExecutorService의 shutdownNow에는 차이가 있다.


stop메소드는 쓰레드를 무조건 중지시킨다. 설령 내부에 멈출 수 없는 무한반복( while(true)와 같은)이 있다고 하더라도 중지시킨다.


그러나, ExecutorService의 shutdownNow는 그렇지 못한다. shutdownNow는 내부 관리되고 있는 쓰레드들에게 인터럽트를 호출해줄뿐이다. (직접 소스를 까보니 그렇더라..)


그리고 이것이 쓰레드가 종료되지 않은 이유이다.

왜냐하면 나는 shutdownNow 메소드가 stop메소드와 같이 중지가 될꺼라고 생각을 하고 쓰레드 내부에 while(true)와 같은 무한반복문을 넣었던 것이다. 그리고 내부에는 인터럽트 되어 지지 않는 sleep과 같은 메소드를 통해서 대기를 하고 있었다.


그러므로 ThreadPool을 통해 사용되어지는 쓰레드는 일반 쓰레드를 구현할 때와 달라야만 한다.


조사와 실험과 개발을 통해 얻은 나의 결론을 적어보겠다.

적으면서 어렴풋히 이전에 본 자바 병행 프로그래밍 책에서 공부한 내용이 떠오른다. 역시 병행 프로그래밍은 그리 만만한 부분이 아니다...후훗..


Java ThreadPool에서 쓰는 쓰레드 설계시 유의사항

1. 무한반복문

어떤 형태로든지 쓰레드가 끝나면 상관 없지만, 웹 애플리케이션과 생명주기를 같이 하는 쓰레드라면 무한반복을 하게 된다. 그런데 이 때 while(true)와 같이 사용하면 안된다. 이 부분은 자바 병행 프로그래밍에 대하여 공부하면 나오는 부분이다. 내가 간과했었다. 


while(isInterrupted()) 와 같이 사용해야 한다.


Runnable의 구현체라면 while(Thread.currentThread().isInterrupted()) 와 같이 사용해야 한다.



2. InterruptedException catch

InterruptedException이 무엇이냐면 외부에서 쓰레드에 대하여 인터럽트를 발생시켰는데 쓰레드가 특정 상태에 빠져서 인터럽트가 걸리지 않아서 발생하는 예외이다.


대표적인 것이 Thread클래스의 sleep메소드이다.

다른 예로는 내가 사용한 LinkedBlockingQueue의 take메소드이다. take메소드는 큐가 비어있다면 큐에 새로운 객체가 들어오기 전까지 대기하게 된다. 즉 sleep메소드처럼 대기하게 되고 이 상태에서는 인터럽트가 걸리지 않게 되는 것이다. 


그러므로 InterruptedException이 발생할 수 있는 메소드는 반드시 잡아내어서(catch) 중지해야 한다.



.



위의 두 가지에 대한 간단한 코드는 다음과 같다.


while(!isInterrupted()) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

break;

} catch (Exception e) {

...

}

}





나와 같은 실수를 하지 않길 바라며, Good luck



Reference

[1] 김용환 블로그 (http://knight76.tistory.com/947)



신고

Comments

  1. 2012.09.23 16:29 Permalink Modify/Delete Reply

    비밀댓글입니다

  2. 아틴 2012.09.24 23:25 신고 Permalink Modify/Delete Reply

    아 죄송하게도 제가 답변을 못 드릴꺼 같네요.

    JDBC와 관련된 메모리 릭은 해결하지 않고 넘어갔던 것 같습니다.
    위에서 적은 것처럼 재시작하는 경우가 아니면 문제가 생기지 않아서요.

Leave a Comment


to Top

티스토리 툴바