월별 글 목록: 2008년 5월월

Object의 Reference에 대한 내용..

자바 플랫폼의 경우 객체에 대해 네 가지 타입의 레퍼런스가 존재하는데, 일반적으로 사용하는 타입으로 Direct Reference를 들 수 있다.

   Object obj = new Object()
특히 Direct Reference는 객체 액세스를 위해 별도의 코딩을 필요로 하지 않는 일반 참조(strong references )라 할 수 있으며, 나머지 세 타입의 레퍼런스는 java.lang.ref 패키지에 포함되어 있는 Reference 클래스의 서브클래스들이다. Soft Reference는 SoftReference 클래스에 의해, Weak Reference는 WeakReference 클래스에 의해, 그리고 Phantom Reference는 PhantomReference 클래스에 의해 제공된다.

Soft Reference는 데이터 캐시와 그 기능이 유사한데, 시스템 메모리가 낮을 때 가비지 컬렉터는 Soft Reference가 유일한 레퍼런스인 객체를 임의로 비울 수 있다. 다시 말해서, 객체에 대한 일반 참조가 없는 경우 그 객체가 릴리즈 후보가 되는 것이다. 한편, 가비지 컬렉터는 OutOfMemoryException을 throw하기 전에 임의의 Soft Reference를 릴리즈해야 한다.

Weak Reference는 Soft Reference보다는 다소 불완전하다. 객체에 대한 유일한 레퍼런스가 Weak Rererence뿐이라면 가비지 컬렉터는 언제라도 오브젝트가 사용하는 메모리를 이용할 수 있으며, 메모리가 낮은 상태라면 별다른 요구사항은 발생하지 않는다. 일반적으로 객체가 사용하는 메모리는 후속 가비지 컬렉터 패스에서 이용된다.

Phantom Reference는 cleanup 작업과 관련이 있다. 이들은 가비지 컬렉터가 마무리 과정을 수행하고 객체를 비우기 바로 직전에 통지를 하는데, 이는 객체 내에서 cleanup 작업을 수행하는 방법 중 한 가지라고 생각하면 된다.

Callable을 사용해서 Runnable의 실행 결과 반환

자바 1.4에 추가된 더그 리(Doug Lea) 교수의 java.util.concurrent 패키지에 Callable과 그 외의 클래스를 사용해서 스레드 풀링 등의 기능을 쉽게 사용할 수가 있다. 아래는 Callable을 사용해서 스레드 실행 결과를 확인하는 내용이다.

그리고 이 내용은 sdnkorea의 내용이었는데, 없어져서 링크는 삭제했다.


저자 John Zukowski
Runnable 인터페이스는 자바 플랫폼 초기부터 사용되어 왔습니다. 이 인터페이스를 사용하면 완료할 작업을 스레드별로 정의할 수 있습니다. 대부분의 사용자들이 이미 알고 있듯이 이 인터페이스는 run() 이라는 단일 메서드를 사용하는데, 이 메서드는 인수를 허용하지 않고 값을 반환하지 않으며 확인된 어떤 예외도 반환할 수 없습니다. 방금 완료된 작업으로부터 값을 반환 받으려면 인터페이스 외부의 메서드를 사용하여 작업이 완료되었다는 일종의 알림 메시지를 기다려야 합니다. 예를 들어, 이러한 시나리오의 경우 다음과 같이 코딩해야 합니다.

 Runnable runnable = ...;
  Thread t = new Thread(runnable);
  t.start();
  t.join();
  String value = someMethodtoGetSavedValue()

원칙적으로 이 코드에 잘못된 점은 없지만 J2SE 5.0에서 소개된 Callable 인터페이스 덕분에 이제는 다른 방법을 사용할 수 있습니다. run() 메서드를 사용하는 대신 Callable 인터페이스는 call() 메서드를 제공하며 이 메서드는 Object를 반환하거나, 보다 구체적으로 generic화된 형식에 사용된 유형을 반환합니다.

public interface Callable<V> {
     V call() throws Exception;
  }

실행할 Thread로 Callable을 전달할 수 없기 때문에 대신 ExecutorService를 사용하여 Callable 개체를 실행합니다. 이 서비스는 Callable 개체를 수락하여 submit() 메서드를 통해 실행합니다.

<T> Future<T> submit(Callable<T> task)

메서드 정의에서 보여 주듯이 Callable 개체를 ExecutorService에 제공하면 Future 개체가 반환됩니다. 그런 다음 Future의 get() 메서드는 작업이 완료될 때까지 차단을 수행합니다. 이것은 첫 번째 예에서 join() 호출과 동일합니다. 실제로 이 메서드는 join() 호출과 동일하며, get()이 Callable 인스턴스에서 계산한 값을 반환할 때 get value 호출과도 동일합니다.

이를 설명하기 위해 다음 예에서는 명령줄에서 전달된 각 단어에 대해 Callable 인스턴스를 개별적으로 만들어 길이를 모두 합산합니다. 각각의 Callable은 개별 단어의 합만을 계산합니다. Future 개체 집합은 각각으로부터 계산된 값을 얻기 위해 저장됩니다. 반환된 값의 순서를 유지해야 할 경우 List를 대신 사용할 수 있습니다.

import java.util.*;
import java.util.concurrent.*;
public class CallableExample {

public static class WordLengthCallable
implements Callable {
private String word;
public WordLengthCallable(String word) {
this.word = word;
}
public Integer call() {
return Integer.valueOf(word.length());
}
}

public static void main(String args[]) throws Exception {
ExecutorService pool = Executors.newFixedThreadPool(3);
Set<Future<Integer>> set = new HashSet<Future&lg;Integer>>();
for (String word: args) {
Callable<Integer> callable = new WordLengthCallable(word);
Future<Integer> future = pool.submit(callable);
set.add(future);
}
int sum = 0;
for (Future<Integer> future : set) {
sum += future.get();
}
System.out.printf("The sum of lengths is %s%n", sum);
System.exit(sum);
}
}

WordLengthCallable은 각 단어를 저장하고 이 단어의 길이를 call() 메서드의 반환 값으로 사용합니다. 이 값은 생성하는 데 시간이 다소 걸릴 수 있지만 이 예에서는 즉시 생성됩니다. call()은 호출 종료 시 반환된 값만을 필요로 합니다. Future의 get() 메서드가 나중에 호출될 경우 이 예에서처럼 작업이 금방 실행되면 Future에서 값을 바로 받고, 작업이 오래 걸릴 경우에는 완료될 때까지 기다립니다. get()을 여러 번 호출한다고 해서 스레드에서 작업이 다시 실행되지는 않습니다.

이 프로그램의 목표는 단어 길이의 합을 계산하는 것이므로 Callable 작업의 완료 순서는 문제가 되지 않습니다. 처음 세 개의 작업이 완료되기 전에 마지막 작업이 완료되어도 상관 없습니다. Future에 대한 첫 번째 get() 호출은 Set의 첫 번째 작업이 완료되기만을 기다립니다. 이는 다른 작업이 개별적으로 실행되는 것을 막지 않으며, 단지 하나의 스레드 또는 작업이 완료되기를 기다립니다.

제공되는 모든 서비스는 고정 크기의 스레드 풀을 사용할 것이므로 이 특정 예에서는 ExecutorService에 대해 고정 크기의 스레드 풀을 사용합니다.

실행자 및 스레드 풀 사용에 대한 자세한 내용은 Java Tutorial의 Executors 단원을 참조하십시오. SwingWorker 클래스는 약간 다르긴 하지만 Future와 함께 작동하는 Runnable 객체의 또 다른 예입니다. 이에 대한 자세한 내용은 Worker Threads and SwingWorker 단원을 참조하십시오.

iBatis에서 MSSQL의 Insert문의 리턴 값 가져오기

Apache iBatis에서 MSSQL DB에 Insert시에 리턴값을 받아오는 형태입니다.

1. 코드
int key = (int)sqlMap.Insert(“InsertOrganization”, organization);

2. xml 내용

<insert id=”InsertOrganization” parameterClass=”Organization” resultClass=”int”>  
    <selectKey property=”Id” type=”post” resultClass=”int”>  
        SELECT @@IDENTITY AS value  
    </selectKey>              
    INSERT INTO Organizations  
        (Org_Code, Org_Name)   
    VALUES   
        (#Code#, #Name#)  
</insert>  

Comparing Two High-Performance I/O Design Patterns

Reactor 패턴과 Proactor 패턴에 대한 비교 자료입니다.
위의 패턴들은 더글라스 슈미츠 박사의 ACE 프레임웍에서 구현을 하였고, 패턴으로 승화가 되었죠.. ^^

아래 내용에서 TProactor 패턴에 대한 얘기가 나오고 있습니다.
소스를 까보면 Leader/Followers 패턴도 적용이 되어 있네요..
결국 기본적으로 IO에 대한 멀티플랙스 + 효율적인 처리를 위한 쓰레드 적용을 통해서 성능을 높이는 것이 TProactor 패턴으로 느껴집니다.

한번씩 읽어보세요.. ^^
 
http://www.artima.com/articles/io_design_patternsP.html