애플리케이션 개발시 종종 구분자로 저장되어있는 문자열 키를 이용해 특정 데이터를 불러와 배열형태로
저장할 필요가 있다.
그럴 경우 아래와 같이 StringTokenizer, ArrayList, VO객체를 이용하여 List 형태로 저장할 수 있다.



List list = new ArrayList();
if(!StringUtil.isBlank(user.getCode())){
    StringTokenizer st = new StringTokenizer(user.getCode(), ",");
    int i = 0;
    while(st.hasMoreElements()) {
        UserVO userVO = UserService.getInstance().getUserInfo(st.nextToken());
        list.add(i, userVO);
        i++;
    }
}



한가지 유의할 점은 list에 객체를 담을때 parameter로 index를 객체와 함께 추가하는 메소드를 사용한다.

Posted by finewoo
,

JDK 다운로드
http://java.sun.com/javase/downloads/index.jsp

리눅스 버전의 .bin파일을
/usr/local/src 에 다운로드
jdk-6u17-linux-i586.bin

root 계정인데도 허가 거부
권한 변경후 설치

# chmod 700 jdk-6u17-linux-i586.bin
# ./jdk-6u17-linux-i586.bin


라이정책 관련된 내용이 출력되는데 엔터키 계속 클릭...
.....
라이선스 동의에 y 입력
설치는 완료
jdk1.6.0_17 디렉토리 생성됨

/usr/local/java 경로로 옮김

#mv jdk1.6.0_17 /usr/local/java


[환경 설정]


#vi /etc/profile

파일 마지막 부분에 JDK 설정 추가

.....

# JAVA SDK 6

JAVA_HOME=/usr/local/java
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH=$
CLASSPATH:$JAVA_HOME/lib/*:.


변경된 내용 적용후 설치버전 확인.

[root@local]# source /etc/profile
[root@local]# javac -version
javac 1.6.0_17


설치완료.







'Linux' 카테고리의 다른 글

[fedora] Sendmail, dovecot, pop3, sasl  (0) 2009.12.21
MySQL설치중 오류:error: No curses/termcap library found  (1) 2009.11.24
Posted by finewoo
,

프로그래밍에서 자주 변하지 않는 일정한 값이나 설정 정보 같은 공용자원에 대한 접근에 있어서 매번 메모리에 로딩하거나 값을 읽어들이는 것보다 일종의 '전역변수'와 같은 개념을 통해 접근하는 것이 비용도 줄이고, 효율도 높일 수 있다. 
자바에는 이런 전역변수 형태의 접근을 가능하게 만들어 주는 static(정적) 이라는 키워드가 있다.

클래스의 변수나 메소드를 static으로 선언하면 그 변수는 객체의 변수가 아니라 클래스 변수가 된다. 클래스 변수이므로 어떠한 객체라도 동일한 주소로 참조하게 된다.
일반적으로 클래스의 변수나 메소드는 해당 클래스가 인스턴스화 되기 전에는 사용할 수 없는데, static 으로 선언된 변수나 메소드는 해당 클래스의 인스턴스 여부와 상관없이 바로 접근이 가능하고, 사용이 가능하다.

그럼 실무에서 적용되는 static 사용의 예로 싱글톤(Singleton)이라는 것을 살펴 보자.

public class Example {  

     /* object 선언 */
    private static Example m_theInstance = null;

    private Example() {
    }
   
    /**
     * Create and Get Instance
     * applied Singleton Pattern.
     */
    public static Example getInstance() {
        if (m_theInstance == null)
            m_theInstance = new Example();
        return m_theInstance;       
    }
}


생성자를 private으로 선언하면 new 로 생성할 수 없게 되고, public static 으로 선언한 getInstance() 메소드를 통해서만 객체에 접근 가능하게 만들어 준다.  Singleton(싱글톤) 방식은 프로젝트에서 데이터베이스 연결등의 공용 자원 접근에 이런 방식의 static 적용하면 효율을 높일 수 있는 한 방법이 될 수 있다.

또다른 예로, 절대 변하지 않는 값을 final static으로 선언하면 GC(Gabage Collection)의 대상이 되지도 않고 클래스 로딩시 메모리에 적재되어 있으므로 효율을 높여 성능향상에 도움이 된다.

지금까지 설명한 static의 효율적인 측면과 함께 반드시 고려해야 할 면으로 static 키워드의 '전역변수'적인 성격때문에 적절하지 않게 사용하게 되면 오히려 시스템에 악영향이 되거나 심각한 오류의 원인이 될 수도 있다는 것을 고려해야 한다.
이말인 즉, 공용자원의 값은 누가 어떤때에 접근하든 일정한 값을 얻어야 하지만 해당 변수나 메소드를 의도하든 그렇지 않든 적절하지 않은 값이 저장될 수도 있다는 것이다.
애플리케이션의 디버깅 작업이나 테스트시 이런 '전역변수'적인 성격의 버그는 예상외로 찾아내기 힘들 수도 있다. 그 패턴이 일정하지 않기 때문이다.

정리하자면, 자주 변경되는 변수나 메소드에 static 키워드는 가능한한(?) 사용하지 않기를 권한다. --;
필요에 따라 static을 선언하게 되더라도 잘못된 값이 참조될 수 있는 부분은 차단하는 것이 바람직하다.

즉, 자주 변경되지 않는 부분이나 설정파일 정보인 경우 등 제한적인 용도로 사용한다면 애플리케이션 성능향상에 충분한 도움이 될 것이다.


Posted by finewoo
,

자바 애플리케이션이 수행되면 서버나 WAS에 프로세스가 생성된다.
그리고 하나의 프로세스에는 하나이상의 Thread(스레드)가 생성된다.
단일 스레드가 생성되었다가 종료될 수도 있고 여러개의 스레드가 생성되고 수행되다가 소멸될 수도 있다. 즉 1대多의 관계다.
스레드는 WAS가 관리하며 시스템 개발시에 스레드를 개발자가 직접 컨트롤하는 일은 별로 없으며, 오히려 제대로 알지 못한 상태에서 직접 제어하면 서비스의 안전성에 문제가 생길 수도 있으니 어떤 원리로 작동되는지 정도만 알아도 충분하다고 본다.

스레드는 같은 프로세스내에서 동일한 데이터를 공유한다. 따라서 하나의 데이터에 대해서 동시에 여러개의 스레드가 접근이 가능하게 되고 그에 따라 데이터의 일관성에 관한 문제가 생길 수가 있다.
그래서 자주 사용되는 것이 synchronized(동기화)이다. 동기화란 하나의 자원(데이터)에 대해서 여러 스레드가 사용하려고 할때 한 시점에서 하나의 스레드만 사용할 수 있도록 하는 것이다.
synchronized 식별자는 보통 메소드의 선언부에 쓰고 이 키워드가 붙은 메소드는 한번에 하나의 스레드만 접근이 가능하며
메소드가 사용중일 때 다른 스레드가 메소드를 호출하면 앞의 스레드가 종료될때까지 기다려야 한다.

이 정도 설명이면 synchronized가 어떤 의미인지는 알 수 있을 것이다.
synchronized는 하나의 객체에 여러개의 객체가 동시에 접근해 처리하는것을 막기위해 사용한다.

public synchronized void exampleMethod() {
//code
...
..
}


private Object obj = new Object();
public void exampleMethod() {
synchronized(obj) {
//code
...
..
}
}


메소드를 동기화하려면 메소드 선언부에 synchronized 식별자를 쓰고, 특정부분을 동기화 하려면 해당 코드 블록에 선언해서
사용하면 된다. 애플리케이션 성능에 있어 이 식별자의 영향력이 막강함에 비해 사용법은 의외(?)로 간단하다.
이말은 거꾸로 해석하자면 synchronized를 잘 알고 쓰면 애플리케이션 자원의 안전성에 득이 되지만 제대로 알지못한 상태에서 남용해서 사용하면 오히려 시스템 성능에 치명적인 독이 될수도 있다는 점을 반드시 인지해야 한다.

그렇다면 어떤 때에 synchronized 식별자를 선언해야 할까?
가장 대표적인 경우이다.

* 하나의 객체에 여러개의 스레드가 접근해서 처리하고자 할때
* static으로 선언한 객체에 여러 스레드가 동시에 사용할때

이런 상황이 발생했을시에 시스템의 안전성 및 데이터의 일관성에 문제가 생길 수 있는 때는
해당 메소드에 동기화를 부여해야 한다.
어쩌다 한번씩 생길 수 있는 오류라고 해도 개발자라면 항상 참이 될도록 가능한한 튼튼한 구조물을 지어야 하지 않을까...

한마디로 줄이자면,  synchronized... 꼭 필요한때만 사용하자!



Posted by finewoo
,

Java Exception handling

자바는 try catch 구문을 사용하여 예외 처리(exception handling)을 하게 되어 있다. 예외가 발생할 수 있는곳에는 모두 예외처리를 하는 것이 좋긴하지만, 개발자들이 잘 알지 못하고 사용한다면 오히려 시스템 성능을 떨어뜨리는 독이 될 수도 있다.

예외처리를 하는데 있어서 몇가지 고려해야 할 점을 알아보자.

예외 처리(exception handling)시에 지켜주어야할 순서가 있고, 순서가 잘못되면 정확한 예외 메시지를 얻을 수 없게 되고, 또한 코드도 복잡해 진다.
일반적으로 예외를 처리에 있어 어떤 메소드를 호출하고 실행할 때, 그 메소드가 어떤 결과값을 반환하고, 어떠한 경우에 예외가 발생하는지를 정확히 알고 있어야 한다. 
즉, 어떤 위치에서 예외가 발생했는지를 정확하게 알 수 있어야 한다.
따라서 다중으로 예외를 선언한 경우에 주의가 필요하다. 만약 어떤 예외를 상속 받아서 새로운 Exception 들을 만들었다면, 상속 받았던 에외들을 먼저 선언해 주어야 한다. 그렇지 않다면, 원하지 안은 결과를 얻을 수도 있다.

아래와 같은 예외처리 코드가 있다고 하자.
JVM 에서는 첫번째 Catch블록에서 부터 호출된 예외를 처리한 Catch블럭을 찾아 내려온다. 만약 처리 가능한 예외 블록이 있다면, 비교를 멈추고 catch블록에 정의된 예외처리 코드들을 실행하게 된다.
따라서 만약에 첫번째 catch블록이 catch(Exception e)라고 정의되어 있다면, 컴파일러는 다른 catch블록이 전혀 필요 없다고 여기고 그 아래 ArrayIndexOutOfBoundsExceptionn e1을 처리하지 않을 것이다.

try {
      code...;
} catch (Exception e) {
     exception handling...;
} catch (ArrayIndexOutOfBoundsExceptionn e1) {
     exception handling...;
}

이런 순서를 모르고서 코드를 작성한다면 의미없는 코드가 되고 결국은 나중에 코드의 문제점을 찾는데 시간이 많이 소요된다.


자바를 개발시에 IDE툴을 많이 사용하게 된다. IDE툴에서는 자동으로 예외처리 코드를 생성해준다

java.io.File file = new java.io.File("c:\\file.txt");
try{
    file.getCanonicalFile();
catch (IOException e) {
    e.printStackTrace();
}

한가지 주위해야 하는 것은 위와 같이 "e.pringStackTrace()"를 툴에서 자동으로 생성해 주었다고, 예외 처리가 모두 끝나는 것이 아니다. 
처리해야할 예외에 대한 후 작업이 있다면 별도 코드를 작성해야 하며 예외를 Log에 남기는 부분도 필요하다. 
Logging또한 "e.printStackTrace()"등의 IDE에서 만들어주는 코드를 그대로 남기는데, 어떤 경우에 예외가 호출되었는지에 대한 정확한 정보를 남기기 위해서 개발자가 나중에 알수 있는 형태의 메시지 형태로 재정의 해서 남겨야 한다.

 예외가 발생했을 경우 가장 판단하기 어려운 때는 try-catch문을 잘못 중첩해서 사용하는 경우인데, 이 경우는 가독성도 떨어지지만, 예외 처리 코드를 분석하기 매우 어렵기 때무에 되도록이면 피하는 것이 좋다.




Posted by finewoo
,