Whiteship's Note


Quartz 사용하기

Java : 2008.03.08 19:47


참조 : http://www.onjava.com/pub/a/onjava/2004/03/10/quartz.html?page=1

필요한 dependency

        <dependency>
            <groupId>quartz</groupId>
            <artifactId>quartz</artifactId>
            <version>1.5.2</version>
        </dependency>

Quartz의 핵심 라이브러리

- Job : 작업을 정의할 때는 이 인터페이스를 구현하고 execute 메소드를 구현해 주어야 합니다.
- SchedulerFactory
    - StdSchedulerFactory : 클래스패스에 quartz.properties 파일을 먹고 삽니다. 프로퍼티 파일의 이름이 이와 같지 않다면, 생성자에 직접 이름을 세팅해 줍니다.
- Scheduler : 스케쥴 팩토리에서 얻어 옵니다. JobDetail과 Trigger를 가지고 스케쥴을 정할 수 있습니다.
- JobDetail : 매번 Job의 객체를 만들지 않고, JobDetail을 사용합니다.
- Trigger : 작업을 언제 실행할 지 정의합니다.
    - SimpleTrigger : interval time, repeat times 등을 설정할 수 있습니다.
    - CronTrigger : Linux의 cron 하고 비슷하게, 특정 시간이 되면 발동하게 해줍니다.

    public static void main(String[] args) {
        try {
            SchedulerFactory schedFact = new org.quartz.impl.StdSchedulerFactory();
            Scheduler sched = schedFact.getScheduler();
            sched.start();
           
            JobDetail jobDetail = new JobDetail("ipNotify", "SLT", IpNotifier.class);
//            SimpleTrigger trigger = new SimpleTrigger("ipNotify", "SLT");
//            trigger.setRepeatInterval(1l);
//            trigger.setRepeatCount(100);
            CronTrigger trigger = new CronTrigger("ipNotify", "SLT");
            trigger.setCronExpression("* 0,30 * * * ?");
           
            sched.scheduleJob(jobDetail, trigger);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

두 종류의 트리거 중에서 저는 CronTrigger가 더 편한 것 같습니다. SimpleTrigger가 무제한 반복할 수 있는 설정을 어떻게 하는지 모르겠어서 말이죠. 덕분에 cron 설정을 공부했습니다.

초 분 시 날 달 주
http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html
top

TAG Quartz
  1. Favicon of https://sunphiz.tistory.com BlogIcon 뒷방늘그니 2009.01.29 10:36 신고 PERM. MOD/DEL REPLY

    늘 글 잘 보고 있습니다.

    마침 제가 찾은게 있어서 덧붙입니다.
    무한 반복은 "use REPEAT_INDEFINITELY for unlimited times." 라고 api가 알려주더군요.
    http://www.opensymphony.com/quartz/api/org/quartz/SimpleTrigger.html

    Favicon of http://whiteship.me BlogIcon 기선 2009.01.29 12:46 PERM MOD/DEL

    오홋.. 글쿤요.
    좋은 정보 감사합니다. :)

Write a comment.


File.delete() 메소드의 리턴값이 false일 경우.

Java : 2008.03.07 19:54


다음 프리마커 매뉴얼에 나와있는 코드 입니다.

import freemarker.template.*;
import java.util.*;
import java.io.*;

public class Test {

    public static void main(String[] args) throws Exception {
       
        /* ------------------------------------------------------------------- */   
        /* You usually do it only once in the whole application life-cycle:    */   
   
        /* Create and adjust the configuration */
        Configuration cfg = new Configuration();
        cfg.setDirectoryForTemplateLoading(
                new File("/where/you/store/templates"));
        cfg.setObjectWrapper(new DefaultObjectWrapper());

        /* ------------------------------------------------------------------- */   
        /* You usually do these for many times in the application life-cycle:  */   
               
        /* Get or create a template */
        Template temp = cfg.getTemplate("test.ftl");

        /* Create a data-model */
        Map root = new HashMap();
        root.put("user", "Big Joe");
        Map latest = new HashMap();
        root.put("latestProduct", latest);
        latest.put("url", "products/greenmouse.html");
        latest.put("name", "green mouse");

        /* Merge data-model with template */
        Writer out = new OutputStreamWriter(System.out);
        temp.process(root, out);
        out.flush();
    }

위에서 사용한 Writer 대신에, FileWriter를 사용하면, 콘솔창에 출력하는 대신, 파일을 생성하도록 할 수 있습니다. 위 코드에서 Writer와 OuputStreamWriter가 아니라, FileWriter로 바꾸고 파일을 하나 만듭니다. 그 다음에 그 파일을 file.delete()를 사용해서 지우려고 하면... 지워 질까요?

안 지워집니다.(뭐... 가.끔.씩. 지워질 수도 있습니다. 아주 가.끔.씩.) 정답은.. 안 갈쳐 줍니다. 캬캬캬캬
top

TAG delete(), File
  1. Favicon of http://gerions.egloos.com BlogIcon 윤걸 2008.03.07 21:48 PERM. MOD/DEL REPLY

    에~ 방금 테스트해보니까 FileWriter 를 close 하니까 삭제되는구만...

    참고로 이런글도 보이는구만..

    http://forum.java.sun.com/thread.jspa?threadID=166271&tstart=45

    쿄쿄쿄

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.03.07 22:03 신고 PERM MOD/DEL

    너무 빨리 맞추시는거 아니에요?
    형 같이 스터디좀 해요~
    안 심심하세요?

  2. Favicon of http://gerions.egloos.com BlogIcon 윤걸 2008.03.08 11:02 PERM. MOD/DEL REPLY

    응? 나만빼고 따로 스터디 하고 있는겨???

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.03.08 11:33 PERM MOD/DEL

    스터디 pre initializing 중이에요.
    참여하세요~

Write a comment.


JNDI 관련 글

Java : 2007.11.01 13:04


Tomcat 5 JNDI DataSource를 통한 DB 커넥션 풀 사용
[05] JNDI (Java Naming And Directory Interface)의 이해 및 실습
JNDI

개념과 동작원리 이해에는 세 번째 글이 좋으며, 실습 용도로는 첫 번째 글이 좋으며, 그 둘을 절충한 듯한 글이 두 번째 글입니다.

발표 준비 마무리 해야하는데.. 자꾸 샛길로 새는군요;ㅋㅋ


'Java' 카테고리의 다른 글

자바의 레퍼런스 클래스 사용 가이드라인  (0) 2008.05.12
Logging/StaticLog  (0) 2008.05.09
Generic 메타데이터 활용하기  (0) 2008.04.27
Quartz 사용하기  (2) 2008.03.08
File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
top

TAG JNDI
  1. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.11.01 14:20 PERM. MOD/DEL REPLY

    샛길이 더 좋아보여요~큭

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.11.01 14:22 신고 PERM MOD/DEL

    ㅋㅋㅋ발표 주제를 바꿔야 하나~
    아 시간 오래 걸리네;

Write a comment.


Java 6에서 @Override

Java : 2007.10.01 12:35


이 애노테이션은 Java 5에 추가된 것입니다. 아시죠?

상속받은 메소드를 재정의 했는지 표현하기 위해서 사용하며 컴파일 할 때 진짜로 해당 메소드가 상위 클래스의 메소드를 오버라이딩 하고 있는 것인지 확인해서, 만약 그렇치 않다면(메소드 시그너처가 다른 경우) 에러 메시지를 보여줍니다.

그런데, Java 6에서는 인터페이스를 구현한 메소드에도 붙여 줄 수 있습니다. Eclipse 3.3에서 Java 6를 무심코 사용하고 계셨다면 어느날 다음과 같은 이상한 에러를 볼 수도 있습니다.
사용자 삽입 이미지

sayGreeting은 인터페이스를 구현하는 메소드 입니다. 애노테이션을 없애거나 Super type에 이 메소드를 정의하라고 합니다. 내참.. 왜이러지? 인터페이스 구현한 건데 왜 @Override를 붙여놨지? 라고 생각하고 없애지 말고 다시 한번 위의 단락에 제가 적어 둔 것을 읽으시기 바랍니다. Java 6에서는 이상한 일이 아닙니다.

프로젝트가 사용하고 있는 JDK 버전을 살펴봤습니다.
사용자 삽입 이미지
6.0이자네.. 근데 왜이러는 거야..
아차!.. 저것은 그냥 참조하는 라이브러리를 보여주고 있을뿐. 실제 컴파일러는 아니잖은가..

프로젝트를 선택한 상태에서 "Alt + 엔터" 클릭하고 왼쪽 메뉴에서 Java Compiler를 선택합니다.
사용자 삽입 이미지
이런..컴파일 레벨이 5.0이였네요. 6.0으로 바꿔주면 에러는 사라집니다. peace~


'Java' 카테고리의 다른 글

Logging/StaticLog  (0) 2008.05.09
Generic 메타데이터 활용하기  (0) 2008.04.27
Quartz 사용하기  (2) 2008.03.08
File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
top

  1. Favicon of https://thystory.tistory.com BlogIcon 불쟁이 2010.03.06 11:11 신고 PERM. MOD/DEL REPLY

    간단 명쾌하군요. 도움 받고 갑니다, 고맙습니다!

    Favicon of http://whiteship.me BlogIcon 기선 2010.03.06 19:54 PERM MOD/DEL

    넵~ 종종 있는 문제죠.ㅋ

  2. Favicon of http://blog.naver.com/iknowchang BlogIcon Chang 2010.04.20 11:56 PERM. MOD/DEL REPLY

    도움 받았습니다. 감사합니다.!

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2010.04.20 14:07 신고 PERM MOD/DEL

    넵~

Write a comment.


쓰레드를 공부하는 학생과의 대화

Java : 2007.09.29 16:24


쓰레드를 공부하고 있는 백기선 인스턴스 두 개의 대화를 공개합니다.

백기선 백기선1 = new 백기선();
백기선 백기선2 = new 백기선();

백기선1.ask(백기선2, "쓰레드는 왜이렇게 어렵죠?");

사실 어려울 것이 없습니다. Thread 객체 하나 만들고, Runnable 인터페이스 구현한 클래스 하나 만들고, Thread.start() 해주면 끝납니다.

백기선1.ask(백기선2, "근데 왜이렇게 어려운 것처럼 느껴지죠?");

자주 사용해보지 않았기 때문이며, 가장 큰 원인은 모든 책들에서 상당히 뒷부분에서 그것도 매우 어렵게 다루고 있습니다. 따라서 배우는 입장에서도 쓰레드가 뭐고 언제 어떻게 사용할 수 있는지 생각할 수 있는 시간이 주어진다기 보다 미리 겁을 주어먹고 도망가고 싶게 만들어 버립니다. 병행성 문제니 데드락이니 동기화 블럭이니 하는 어려운 단어들이 머리속을 휘저으면서 어서 빨리 도망가 버리라고 재촉을 하지요. 사실은 간단한데 말이죠.

백기선1.ask(백기선2, "진짜로 그렇게 간단한가요?");

네. 간단합니다. 쓰레드가 여러개라고 해서 문제 될 것이 뭐가 있죠? 코딩하는 사람이 쓰레드 실행 순서를 관리하는 것도 아니고 그냥 start()만 해주고 정.. 필요하다면 잠깐 멈췄다가 깨워주는 정도의 일만 하면 되는 걸요. 그런 최소한의 비용으로 굉장히 재밌는 프로그램을 만들 수도 있습니다.
예를 들어, mp3 플레이어와 문서 편집기를 합친 애플리케이션을 만들 수도 있습니다. mp3 플레이어를 하나 만들고 실행 파일을 Runnable 인터페이스를 구현하도록 수정하고 내부 코드를 조금 수정(main에 있던 내용을 run 안으로 이동시켜야 겠죠.)하고 편집기 만든 다음에 역시 실행 파일을 Runnable 구현하도록 수정한 다음에 새로운 실행파일을 작성한 다음에 거기서 Thread 두 개 만든 다음에 위에서 Runnable을 구현하도록 수정한 것들을 생성자에 넣어주고 각각을 start() 시켜주면 됩니다.

백기선1.ask(백기선2, "진짜로 그렇게해도 아무 문제가 발생하지 않나요?");

mp3 애플리케이션과 문서 편집기만 제대로 작성했다면 당연히 아무런 문제도 발생하지 않습니다. 왜냐면 두 쓰레드가 서로 공유하는 자원이 아무것도 없기 때문에 전~~~~~~~~혀 걱정할 것이 없습니다.

백기선1.ask(백기선2, "공유하는 자원이요?");

네. 여러 쓰레드를 사용(멀티 쓰레드, Concurrent 프로그래밍)할 때 프로그래밍이 어려워 지는 이유는 딱 하나. 공유하는 자원 때문입니다. 여러 쓰레드가 하나의 자원에 접근할 때 여러 문제가 발생할 수 있는데 그것 때문에, 동기화(롹킹) 블럭이라는 대안책이 나온거고, 그 대인책이 또 다른 문제를 발생시킬 수도 있으며, 동기화라는 것 자체가 쉬운일이 아니기 때문에 Concurrent 프로그래밍이 어려운 것입니다. 이 모든 문제의 원인이 바로 여러 쓰레드들이 공유하는 자원이 있기 때문입니다.

백기선1.ask(백기선2, "여러 명이 공유하는 자원이라... 어떤 것이 있죠? 잘 안 와닿습니다.");

가장 유명한 것으로 "데이터베이스"라는 것이 있습니다. 자료의 저장소로써 여러 명이 이 하나의 저장소 또는 여러 저장소에 있는 자료를 꺼내보거나 집어 넣거나 수정하는 일들을 통해서 여러가지 이익 창출을 하기도 합니다. 그놈의 데이터가 뭔지.. @_@ 암튼. 딱 DB야 말로 여러 명이 공유하는 자원에 가장~ 적합한 예에 해당합니다.
워드 문서파일도 마찬가지죠. 하나의 파일을 두 개의 편집기에서 동시에 열고 작업한다고 생각해 보세요.

백기선1.ask(백기선2, "그럼 멀티 쓰레드가 하나의 자원에 접근할 때 발생하는 문제와도 관계가 있겠군요.");

당연하죠. 그래서 DB에서 발생할 수 있는 Concurrency Problems을 살펴보시면 이 문제들이 자바 애플리케이션에서도 고대~로 나타날 수 있는 것들임을 직작할 수 있을 것입니다.

'Java' 카테고리의 다른 글

Generic 메타데이터 활용하기  (0) 2008.04.27
Quartz 사용하기  (2) 2008.03.08
File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
top

  1. Favicon of http://soharang.tistory.com BlogIcon 소하랑 2011.03.25 08:56 PERM. MOD/DEL REPLY

    재밌게 잘 설명해주셨네요..ㅎ 잘 보고 갑니다.

Write a comment.


Concurrent Programming with J2SE 5.0

Java : 2007.09.29 15:17


참조 : http://java.sun.com/developer/technicalArticles/J2SE/concurrency/

Concurrency problem을 검색하다가 발견한 링크 입니다. Java 5에 추가되었다던 기능들을 어느 정도 살펴봤다고 생각하고 있었지만, 착각이였습니다.

"뉴욕의 프로그래머"를 보면 Java 5 이전 버전에서 사용하던 synchronized 블럭, Object.wait(), and Object.notify() 들이 비효율적이기 때문에 어떤 교수가 만들어서 사용하고 있던 Concurrent API를 Java 5에 추가했다. 라는 내용이 있습니다.

바로 그 부분에 해당하는 내용을 간략하게 소개한 아티클로 2005년에 작성된 문서인데 Agile Java 스터디를 준비하다가 2007년 9월 막바지에 발견하게 되었습니다.

현재는 위의 내용을 정리하기 전에 Thread를 어떻게 사용하고, 사용할 때 어떤 문제들이 발생할 수 있는지 정리하고 있습니다. 그리고 그 문제들을 어떻게 방지할 수 있는지 정리한 다음에 위의 문서를 정리할 생각입니다.

'Java' 카테고리의 다른 글

Quartz 사용하기  (2) 2008.03.08
File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
top

  1. Favicon of http://humbleprogrammer.net/blog BlogIcon 험블 2007.09.29 17:49 PERM. MOD/DEL REPLY

    임백준님의 책은 못 보았지만, Doug Lea의 Concurrent 라이브러리를 지칭하는 것같네요.
    Joshua Bloch가 쓴 Java Concurrency in Practice 가 가장 최근의 자바 병행프로그래밍 이슈를 다룬 책이라고들 하는데 아마 concurrent 라이브러리를 위주로 설명하는듯 합니다. 저도 병행프로그래밍쪽은 쥐약이라, 언제 시간나면 공부해야지 생각만 했는데, 정리해주시는 자료 감사히 잘 보겠습니다^^

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.09.29 18:17 신고 PERM MOD/DEL

    네 딱 그거네요.
    책도 옆에 있지만, 찾기가 귀찮아서 저렇게 써놨는데 감사합니다. ㅎㅎ

Write a comment.


All About Sockets 2

Java : 2007.09.26 15:07


Reading from and Writing to a Socket

import java.io.*;
import java.net.*;

public class EchoClient {
    public static void main(String[] args) throws IOException {

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try {
            echoSocket = new Socket("taranis", 7);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(
                                        echoSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: taranis.");
            System.exit(1);
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for "
                               + "the connection to: taranis.");
            System.exit(1);
        }

    BufferedReader stdIn = new BufferedReader(
                                   new InputStreamReader(System.in));
    String userInput;

    while ((userInput = stdIn.readLine()) != null) {
        out.println(userInput);
        System.out.println("echo: " + in.readLine());
    }

    out.close();
    in.close();
    stdIn.close();
    echoSocket.close();
    }
}

클라이언트 쪽에서 Socket을 사용하는 방법은 매우 간단합니다.
먼저 Socket 객체를 만들기 위해서 생성자에 서버의 IP 와 포트넘버를 생성자에 넘겨줍니다.
그리고 서버에 어떤 메시지를 보내기 위해서는 PrintWriter를 사용하고, 서버로 부터 데이터를 받아 오기 위해서는 BufferedReader를 사용하면 됩니다. 물론 두 객체는 모두 Socket을 사용하여 생성합니다.
마지막으로 열려있는 자원들을 close 해줌으로써 메모리 누수를 방지합니다.

클라이언트 프로그램 구현 절차는 다음과 같습니다.
   1. Open a socket.
   2. Open an input stream and output stream to the socket.
   3. Read from and write to the stream according to the server's protocol.
   4. Close the streams.
   5. Close the socket.

Writing the Server Side of a Socket
import java.net.*;
import java.io.*;

public class KnockKnockServer {
public static void main(String[] args) throws IOException {

ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}

Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}

PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
String inputLine, outputLine;
KnockKnockProtocol kkp = new KnockKnockProtocol();

outputLine = kkp.processInput(null);
out.println(outputLine);

while ((inputLine = in.readLine()) != null) {
outputLine = kkp.processInput(inputLine);
out.println(outputLine);
if (outputLine.equals("Bye."))
break;
}
out.close();
in.close();
clientSocket.close();
serverSocket.close();
}
}
위의 코드에서 주목해야 할 부분에 빨간색으로 표시해 두었습니다.
ServerSocket를 생성하여 클라이언트의 접속을 받아들일 준비를 합니다. 이 때 클라이언트의 요청을 받을 포트 번호를 생성자에 넘겨줍니다.
그런 다음 클라이언트에서 요청이 오면(serverSocket.accept()) 새로운 Socket 객체를 만들고, 그 Socket과 클라이언트 간에 의사소통을 위한 PrintWriter와 BufferedReader 객체를 생성합니다.
그리고 나서 서버에서는 클라이언트로 부터 BufferedReader 객체를 사용하여 데이터를 읽어오고, 읽어온 데이터를 처리하고, 마지마긍로 PrintWriter를 사용하여 다시 클라이언트에게 결과를 보내줍니다.

KnockKnockClient

여기까지는 매우 간단합니다.

만약에 위와 같은 상황에서 클라이언트 100가 하나의 서버에 접속하게 되면 어떻게 될까요? 100번째 클라이언트는 앞에 있는 99개의 클라이언트와 서버의 접속이 끝날 때까지 기다려야 합니다. 이럴 때 쯤 등장하는 녀석이 바로 멀티쓰레드.

위의 서버 클래스는 클라이언트의 접속을 받은 다음 새로운 소켓을 만들어서 Thread로 넘겨주는 일만 하고, 실제 클라이언트와 열심히 읽고 쓰는 일은 Thread가 알아서 하도록 하면 100번째 클라이언트가 기다리는 시간은 오직 자신을 위해 일해 줄 서버의 소켓을 생성하는 시간밖에 되지 않을 겁니다.

KKMultiServer, KKMultiServerThread

2007/09/26 - [Java] - All About Sockets 1

'Java' 카테고리의 다른 글

File.delete() 메소드의 리턴값이 false일 경우.  (4) 2008.03.07
JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
top

Write a comment.


All About Sockets 1

Java : 2007.09.26 13:49


참조 : http://java.sun.com/docs/books/tutorial/networking/sockets/index.html

앞에서 살펴보았던 URL과 URLConnection 객체를 사용한 프로그래밍은 상당히 높은 추상화 단계에서 접근하는 것입니다. 하지만 만약 클라이언트-서버 프로그래밍을 하게 된다면, 매우 구체적은 단계에서 접근할 필요가 있습니다.

클라이언트-서버 프로그램들은 각자 소켓을 사용하여 서로를 연결하고 있으며 자신이 가지고 있는 소켓을 통해서 읽기 쓰기 작업을 합니다.

What Is a Socket?

네트워크에서 동작 중이 두 개의 애플리케이션을 잇는 Endpoint로 포트 번호를 사용하여 TCP 계층에서 보내진 데이터가 어떤 애플리케이션을 위한 것인지 식별할 수 있도록 합니다.

서버쪽에서는 클라이언트가 접속할 Endpoint로 특정 포트 번호를 사용하여 Socket을 생성합니다.
사용자 삽입 이미지
그리고 해당 Socket으로 접속이 오면 새로운 Socket을 만들어서 접근해온 Client의 IP와 포트 번호를 설정합니다. 왜냐면, 다른 클라이언트의 접속들도 동일한 Socket으로 받아들이기 위해서입니다.
사용자 삽입 이미지
즉, 모든 접속은 한 Socket에서 받아 들이고, 새로운 접속이 올 때마다 Server쪽에 새로운 Socket을 생성하여 그 Socket과 클라이언트의 Socket이 의사소통을 하게 됩니다.

자바에서 Socket을 위해 제공하는 API로 Socket와 SeverSocket이 있습니다. ServetSocket이 위에서 언급한 접속을 받아 들이기 위한(listerner) Socket을 위한 구현체이고, Socket은 그 이외의 모든 Socket을 위한 구현체 입니다.

2007/09/26 - [Java] - Java에서 URL 다루기 2
2007/09/18 - [Java] - Java에서 URL 다루기 1


'Java' 카테고리의 다른 글

JNDI 관련 글  (2) 2007.11.01
Java 6에서 @Override  (4) 2007.10.01
쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
top

Write a comment.


Java에서 URL 다루기 2

Java : 2007.09.26 12:37


Connecting to a URL

URL 객체를 생성한 다음 openConnection 메소드를 사용하여 URLConnection 객체를 생성할 수 있습니다. 다음은 Yahoo.com URL의 Connection 객체를 만드는 예제 코드입니다.

try {
    URL yahoo = new URL("http://www.yahoo.com/");
    URLConnection yahooConnection = yahoo.openConnection();
    yahooConnection.connect();

} catch (MalformedURLException e) {     // new URL() failed
    . . .
} catch (IOException e) {               // openConnection() failed
    . . .
}

URLConnection.connect 메소드를 사용하여 Connection을 초기화 할 수 있는데 매번 명시적으로 호출하지 않아도 됩니다. getInputStream, getOutputStream 같은 메소드를 호출할 때 암묵적으로 호출하기 때문입니다.

Reading from and Writing to a URLConnection

URLConnection 클래스는 네트워크를 사용하여 URL과 의사소통을 하기 위한 다양한 메소드를 제공합니다. HTTP를 위한 기능들이 많이 있지만, 대부분의 다른 프로토콜을 위한 기능도 제공하고 있습니다.

Reading from a URLConnection

URL에서 직접 읽어오기와 비슷합니다.

import java.net.*;
import java.io.*;

public class URLConnectionReader {
    public static void main(String[] args) throws Exception {
        URL yahoo = new URL("http://www.yahoo.com/");
        URLConnection yc = yahoo.openConnection();
        BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                yc.getInputStream()));
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        in.close();
    }
}

Writing to a URLConnection

URLConnection 객체를 사용하여 OutputStream 객체를 얻어서 ObjectOutputStream을 생성한 다음 URL로 원하는 데이터를 posting 한 뒤에 서버에서 처리한 결과를 URLConnection객체의 InputStream을 받아서 BufferedReader로 읽는 프로그램입니다.
import java.io.*;
import java.net.*;

public class Reverse {
public static void main(String[] args) throws Exception {

if (args.length != 2) {
System.err.println("Usage: java Reverse " +
"http://<location of your servlet/script>" +
" string_to_reverse");
System.exit(1);
}

String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

URL url = new URL(args[0]);
URLConnection connection = url.openConnection();
connection.setDoOutput(true);

OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("string=" + stringToReverse);
out.close();

BufferedReader in = new BufferedReader(
new InputStreamReader(
connection.getInputStream()));

String decodedString;

while ((decodedString = in.readLine()) != null) {
System.out.println(decodedString);
}
in.close();
}
}
2007/09/18 - [Java] - Java에서 URL 다루기 1

top

  1. Favicon of https://wannastopa.tistory.com BlogIcon 류재섭 2009.05.11 02:06 신고 PERM. MOD/DEL REPLY

    잘 봤습니다.

    퍼갈께요~~

    좋은 자료 감사합니다. ~~

    Favicon of http://whiteship.me BlogIcon 기선 2009.05.11 07:55 PERM MOD/DEL

Write a comment.


Java에서 URL 다루기 1

Java : 2007.09.18 10:35


참조 : http://java.sun.com/docs/books/tutorial/networking/urls/index.html

What Is a URL?

Uniform Resource Locator의 약자로 인터넷에 있는 자원(Resource)를 의미합니다.
사용자 삽입 이미지
Protocol identifier는 자원을 가져올 때 사용할 프로토콜을 나타냅니다.
Resource Name은 자원의 주소를 나타내며, 보통 다음과 같은 구성요소로 이루어져있습니다.
Host Name, File Name, Port Number, Reference

Creating a URL

일반 객체를 생성하듯이 new 키워드를 사용합니다.
URL gamelan = new URL("http://www.gamelan.com/");

상대경로는 다음과 같이 사용할 수 있습니다.
URL(URL baseURL, String relativeURL)

예를 들어, 다음과 같은 두 개의 URL에 상대경로가 있다고 가정하겠습니다.(실제로 있을지도;;)
http://www.gamelan.com/pages/Gamelan.game.html
http://www.gamelan.com/pages/Gamelan.net.html

이 때 위의 두 URL에 다음과 같이 상대경로로 접근할 수 있습니다.
URL gamelan = new URL("http://www.gamelan.com/pages/");
URL gamelanGames = new URL(gamelan, "Gamelan.game.html");
URL gamelanNetwork = new URL(gamelan, "Gamelan.net.html");

URL addresses with Special characters

URL에 특수 문자(예, 빈칸)가 있을 때는 URI를 사용한다음에 이것을 URL로 변환하면 URI에서 알아서 특수문자를 변환해 줍니다.

URI uri = new URI("http", "foo.com", "/hello world/", "");
URL url = uri.toURL();

MalformedURLException

URL 객체를 생성할 때 해당 URL 자원이 존재하지 않거나 올바르지 않은 프로토콜일 경우에 MalformedURLException 예외가 발생합니다. 이 예외는 catched exception이기 때문에 try-catch문으로 URL 생성코드를 감싸줘야 합니다.
try {
    URL myURL = new URL(. . .)
} catch (MalformedURLException e) {
    . . .
    // exception handler code here
    . . .
}

Parsing a URL

아래의 코드를 보면 URL에 어떤 메소드들이 있는지 알 수 있습니다.
import java.net.*;
import java.io.*;

public class ParseURL {
    public static void main(String[] args) throws Exception {
        URL aURL = new URL("http://java.sun.com:80/docs/books/tutorial"
                           + "/index.html?name=networking#DOWNLOADING");
        System.out.println("protocol = " + aURL.getProtocol());
    System.out.println("authority = " + aURL.getAuthority());
        System.out.println("host = " + aURL.getHost());
        System.out.println("port = " + aURL.getPort());
        System.out.println("path = " + aURL.getPath());
        System.out.println("query = " + aURL.getQuery());
        System.out.println("filename = " + aURL.getFile());
        System.out.println("ref = " + aURL.getRef());
    }
}

결과는 다음과 같습니다.
protocol = http
authority = java.sun.com:80
host = java.sun.com
port = 80
path = /docs/books/tutorial/index.html
query = name=networking
filename = /docs/books/tutorial/index.html?name=networking
ref = DOWNLOADING

Reading Directly from a URL

다음과 같은 코드를 사용하여 URL에서 직접 콘텐츠를 읽어 들일 수 있습니다.
import java.net.*;
import java.io.*;

public class URLReader {
    public static void main(String[] args) throws Exception {
    URL yahoo = new URL("http://www.yahoo.com/");
    BufferedReader in = new BufferedReader(
                new InputStreamReader(
                yahoo.openStream()));

    String inputLine;

    while ((inputLine = in.readLine()) != null)
        System.out.println(inputLine);

    in.close();
    }
}


'Java' 카테고리의 다른 글

쓰레드를 공부하는 학생과의 대화  (1) 2007.09.29
Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
top

TAG URL

Write a comment.


자바 네트워크 프로그래밍 기초 지식

Java : 2007.09.17 21:39


참조 : http://java.sun.com/docs/books/tutorial/networking/overview/networking.html

인터넷으로 연결되어 있는 컴퓨터끼리 의사소통을 하기 위해서 TCP(Transmission Control Protocol) 또는 UDP(User Datagram Protocol)를 사용합니다.

사용자 삽입 이미지

프로그램 작성은 Application 계층에서 하기 때문에 TCP와 UDP에 대해 자세히 알아둘 필요는 없지만, 그래도 TCP를 사용할 때 사용하는 API와 UDP를 사용할 때 사용하는 API도 다르고, 살짝 차이점 정도 알아 둬서 나쁜 것은 없습니다.

TCP

신뢰성있는 의사소통을 필요로 할 때 사용하는 방법으로, 의사소통을 하려는 두 지점(Peer) 사이에 커넥션을 만들고, 해당 커넥션을 사용하는 방법입니다. 따라서 커넥션 기반 프로토콜이라도고 합니다. TCP는 전화 통화에 비유할 수 있는데요. 전화를 걸면 상대방과 전화선을 타고 연결이 되고 그 연결된 전화선을 통해서 음성 데이터를 주고 받습니다. 물론 말한 순서대로 상대방에게 들리는 것과 같이, TCP를 사용하는 전송에서의 데이터는 보내는 순서에 따라 목적지에 도착하게 됩니다. 주로 HTTP, FTP 등 대부분의 서비스 들이 TCP를 사용합니다.

UDP

TCP를 사용하는 서비스와 달리 데이터를 전송할 때 굳이 지속적으로 연결되어 있을 필요가 없으며, 신뢰성이 필요하지 않은 경우에 UDP를 사요할 수 있습니다. UDP는 데이터그램이라는, 데이터를 독립적으로 쪼갠 패킷을 사용합니다. 데이터그램을 목적지로 보내는 것을 편지를 보내느 것으로 비유하고 있습니다. 다수의 편지를 보내지만, 어떤 순서대로 도착할지 알 수도 없으며 관심도 없는 편지와 유사합니다.

포트 이해하기

여러 데이터를 목적지로 보냈는데 대체 어떤 애플리케이션을 위한 데이터인지 어떻게 알 수 있을까요? 그것을 구분할 수 있는 것이 바로 포트입니다. 하나의 포트는 하나의 애플리케이션을 위한 데이터를 받아들이는 출입구로 생각하면됩니다. TCP를 사용할 때는, 특정 포트를 소켓에 설정해 두고 해당 애플리케이션에서 원하는 데이터를 받아들이도록 합니다.
사용자 삽입 이미지
UDP를 사용할 떄는 데이터그램 패킷에 포트 번호를 포함하고 있습니다. 그리고 UDP가 해당 패킷을 적당한 포트로 라우팅합니다.
사용자 삽입 이미지

포트 번호는 0번부터 65,535까지 사용할 수 있으며 그 중에서 0부터 1023 까지는 HTTP, FTP, SMTP와 같은 시스템 서비스를 위한 예약된 포트로 지정되어 있기 때문에 사용을 자제하시기 바랍니다.

Networking Classes in the JDK

TCP를 사용할 때 : URL, URLConnection, Socket, ServerSocket
UDP를 사용할 때 : DatagramPacket, DatagramSocket, MulticastSocket

'Java' 카테고리의 다른 글

Concurrent Programming with J2SE 5.0  (2) 2007.09.29
All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
top

Write a comment.


Autoboxing의 오묘함

Java : 2007.09.09 21:07


오늘 AJN에서 Agile Java 스터디를 하던 중 예전에 작성했던 Auto (un)boxing은 -128~127 (4) 이 글을 살펴보게 되었습니다.

저 글을 작성할 당시 저 내용을 저도 제대로 이해하고 있지 않았었는데 이번에는 좀 더 이해가 되면서 오히려 의문스러운 점이 발생했습니다.(말이 좀 이상하지만;;)

간략하게 요약하면 다음과 같습니다.
        checkIntegerSame(127, 127); // same

        checkIntegerSame(128, 128); // Not same

        checkIntegerEquals(128, 128); // equals

        checkIntegerSame(-128, -128); // same

        checkIntegerSame(-129, -129); // Not same

        checkIntegerEquals(-129, -129); // equals

위와 같은 호출이 있을 때 다음과 같은 결과가 나옵니다.
ii = 127, jj = 127 ==> jj is same ii.
ii = 128, jj = 128 ==> jj is NOT same ii!!
ii = 128, jj = 128 ==> jj is equals ii.
ii = -128, jj = -128 ==> jj is same ii.
ii = -129, jj = -129 ==> jj is NOT same ii!!
ii = -129, jj = -129 ==> jj is equals ii.

checkIntegerSame 메소드와 checkIntegerEquals 메소드는 다음과 같습니다.

    private static void checkIntegerSame(Integer ii, Integer jj) {
        if (ii == jj) {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is same ii.");
        }
        else {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is NOT same ii!!");
        }
    }

    private static void checkIntegerEquals(Integer ii, Integer jj) {
        if (ii.equals(jj)) {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is equals ii.");
        }
        else {
            System.out.println("ii = " + ii + ", jj = " + jj + " ==> jj is NOT equals ii!!");
        }
    }

이상하지 않으신가요..

맨 위에서 호출한 메소드들에 넘겨준 값들은 모두 primitive 타입 입니다. 그 값들이 checkIntegerSame 이 메소드의 인자로 넘어갈 때 Autobixing이 일어납니다.(Java 5 이상에서) 그래서 각각의 메소드에서 == 비교를 하는데...

이상한 부분은 제일 첫 번째 메소드 호출 checkIntegerSame(127, 127); 의 결과가 ii = 127, jj = 127 ==> jj is same ii. 이렇게 나왔다는 것입니다. 어떻게 같게 나올 수 가 있을까요?

        if(new Integer(127) == new Integer(127)){
            System.out.println("오.. 말도 안돼...");
        }

위의 코드를 실행해서 "오.. 말도 안돼.."가 출력되는 거랑 같은 상황인 겁니다.(물론 위의 코드는 false가 되기 때문에 아무것도 출력하지 않습니다. 테스트 해 봤습니다.)

그렇다면 내릴 수 있는 가설은 하나....(지금 제 머릿속에서는 이것 밖에 생각이 나지 않습니다.)

Autoboxing을 할 때 -128~127의 정수 값들은 Immutable한 Integer 객체로 다뤄지고 그 범위를 벗어나는 객체들은 매번 새로운 객체로 만들어 진다.

무슨 말인고 하니.. 예를 들어, String s1 = "hi"; String s2 = "hi"; 이 때 다음과 같이 비교를 하면

if(s1 == s2) {
 sysout("당연하지");
}

"당연하지"를 출력합니다. String 객체를 ""를 사용하여 만들 때 Immutable하게 만들기 때문입니다. 그러나 new 키워드를 사용하면 그렇치 않고 매번 객체를 생성하게 되죠. 이것과 마찬가지의 일이 Autoboxing에서도 일어나고 있다고 가설을 내려 봅니다.


'Java' 카테고리의 다른 글

All About Sockets 2  (0) 2007.09.26
All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
Factory Method vs Constructor  (0) 2007.05.18
top

  1. Favicon of https://hyukhur.tistory.com BlogIcon 헉군 2007.09.10 16:45 신고 PERM. MOD/DEL REPLY

    flyweight 패턴 비슷하게 구현된 것 아닐까요?

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.09.10 19:40 신고 PERM MOD/DEL

    그런듯 합니다.

    Flyweight 패턴을 자세히 보진 않고
    http://compstat.chonbuk.ac.kr/rightway/designpatterns/flyweight.html
    여기를 참조해서 살펴보았는데요. 왠지 그런 것 같네요.

    좋은 정보 감사합니다. :)

Write a comment.


객체 크기 구하기

Java : 2007.08.14 21:52


Object 클래스에 size() 라는 메소드가 없습니다. 그럼 객체의 크기를 알 수 없을까요;;

약간 돌아가면 알 수 있습니다. Runtime 이라는 클래스를 사용하여 힙 영역의 크기를 재면 됩니다.

public class Size {
    public static void main(String[] args) {
        System.gc();
        Runtime r = Runtime.getRuntime();
        System.out.println("전체 힙 메모리" + r.totalMemory());
        long firstMemorySize = r.freeMemory();
        System.out.println("가용한 힙 메모리" + firstMemorySize);
        Object[] o = new Object[10000];
        for(int i = 0 ; i < 10000 ; i++){
            o[i] = new Object();
        }
        long lastMemorySize = r.freeMemory();
        System.out.println("객체 생성 후 가용한 힙 메모리" + lastMemorySize);
        System.out.println("Object 객체 하나의 메모리 크기는 " + (firstMemorySize - lastMemorySize)/10000);
    }
}
전체 힙 메모리5177344
가용한 힙 메모리5021040
객체 생성 후 가용한 힙 메모리4917928
Object 객체 하나의 메모리 크기는 10

재미있는 건 JVM 또는 JRE 마다 객체의 크기가 다르다는 것입니다.
위의 결과는 JDK6.0 정확히 JRE1.6.0_01 에서 확인한 결과고.. 같은 코드를 JRE 1.5.0_10에서 확인한 결과는 다음과 같스비낟.

전체 힙 메모리2031616
가용한 힙 메모리1884632
객체 생성 후 가용한 힙 메모리1773680
Object 객체 하나의 메모리 크기는 11

1 차이가 나네요. String 객체의 크기도 재미삼아 재봤습니다.

6.0에서는 42
전체 힙 메모리5177344
가용한 힙 메모리5021040
객체 생성 후 가용한 힙 메모리4595032
String 객체 하나의 메모리 크기는 42

5.0에서는 44
전체 힙 메모리2031616
가용한 힙 메모리1884632
객체 생성 후 가용한 힙 메모리1444456
String 객체 하나의 메모리 크기는 44


'Java' 카테고리의 다른 글

All About Sockets 1  (0) 2007.09.26
Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
Factory Method vs Constructor  (0) 2007.05.18
효율적인 문자열 연결 방법  (2) 2007.05.18
top

  1. kris jeong 2009.12.31 16:06 PERM. MOD/DEL REPLY

    좋은 자료 얻어갑니다.
    아래는 IBM JDK의 command 콘솔에서의 실행 결과입니다.
    그런데 Eclipse에서의 실행결과와 콘솔 실행결과가 좀 다르게 나오네요..

    os.name : Windows XP
    os.version : 5.1 build 2600 Service Pack 3
    java.vm.specification.vendor : Sun Microsystems Inc.
    java.fullversion : J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223-20060504 (JIT enabled)
    J9VM - 20060501_06428_lHdSMR
    JIT - 20060428_1800_r8
    GC - 20060501_AA

    java.vm.info : J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32 j9vmwi3223-20060504 (JIT enabled)
    J9VM - 20060501_06428_lHdSMR
    JIT - 20060428_1800_r8
    GC - 20060501_AA

    java.runtime.name : Java(TM) 2 Runtime Environment, Standard Edition
    java.vm.name : IBM J9 VM
    java.runtime.version : pwi32dev-20060511 (SR2)

    Total heap memeory 4194304
    Available heap memory 3665328
    After Object creation, Available heap memory 3411768
    One Object's memory siae 25

    참고하세요..

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2010.01.02 07:50 신고 PERM MOD/DEL

    흠.. 그렇군요. 하두 오래전 글이라 객체 크기를 왜 구하려고 했었는지 기억도 안나네요.ㅋ

Write a comment.


때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)

Java : 2007.08.10 14:29


원문 : Sometimes it's best not to share

Threading lightly 라는 시리즈 중에 3부에 해당하는 내용으로 직역하자면 '가볍게 쓰레딩하기' 정도가 되겠습니다. 멀티쓰레드 환경에서 Thread-safety를 보장하는 일이 꽤 까다로운 편인데, 이러한 글들로 도움을 주는 멋쟁이들이 있으니 참으로 편하게 공부할 수 있는 세상이 아닌가 싶습니다.

제목이 저런 이유는 간단합니다. 멀티쓰레드 환경에서 Thread-safety 문제가 발생하는 원인이 바로 여러 쓰레드에서 공유 자원에 접근하기 때문인데, 바로 그 점을 ThreadLocal을 사용하여 각 쓰레드에서 사용할 데이터를 분리 시키면 Thread-safety 문제를 걱정할 필요없다는 점에서 이런 재밌는 제목을 지은 것 같습니다.

참조 & 요약 & 번역

예를 들어, JDBC connection여러 쓰레드에서 공유하여 사용하는 것은 매우 세밀하게 보면 불가능 하다. 그러나 각각의 쓰레드마다 Connection 객체를 가지게 되면 그런 일을 걱정하지 않아도 된다. 물론 Thread API에서도 다른 객체와 연관하는 기능을 지원하지만(전 잘 모르겠지만;; 그렇다는 군요.), ThreadLocal을 사용하는 것이 더 간단하다.

What is a thread-local variable?

쓰레드 로컬 변수는 각각의 쓰레드가 사용하는 값의 분리된 복사본을 효율적으로 제공한다. 각각의 쓰레드는 오직 자기 자신과 연관된 값만 참조할 수 있으며 다른 쓰레드들이 어떤 것을 사용하는지 그들의 복사본을 수정했는지는 알 수 없다.

다른 언어에서는 storage-class modifier(static 또는 volatile) 를 사용하여 쓰레드 로컬 변수를 지원 하지만 자바는 그렇치 않고 쓰레드 로컬의 구현체인 ThreadLocal 클래스를 제공한다.(자바에도 static 이랑 volatile이 있는데.. 이 글을 작성할 시점에는 아직 volatile이 없었나 봅니다. 근데 지금도 volatile은 잘 안쓰이는 것으로 알고 있는데 아마 이러한 의도로 만들어진 키워드 같네요.)

자바에서는 키워드가 아니라 클래스기 때문에 아무래도 다른 언어에 비해 사용하기가 다소 번잡하다. 쓰레드 로컬을 사용하려면 ThreadLocal 객체를 만들어 사용하면 된다.

Using ThreadLocal to implement a per-thread Singleton

쓰레드 로컬 변수는 보통 상태를 유지하는 싱글톤(stateful Singleton)을 사용하기 위해서 또는 공유 객체의 thread-safe를 위해서 사용한다. 각각 전체 객체를 Threadlocal에 넣거나 객체의 쓰레드 관련 상태를 ThreadLocal에 넣어서 캡슐화(encapsulation)하는 방법을 사용한다.

예를 들어, JDBC Connection 객체를 사용하는 프로그램에서 이 객체를 모든 메소드의 인자로 넘겨주는 것은 상당히 불편한 일이다. 그래서 singleton 객체를 사용하는데 이 때 멀티쓰레드 환경이라면 thread-safe를 보장하지 못한다. 따라서 다음과 같은 코드를 사용하여 ThreadLocal로 쓰레드 당 싱글톤으로 Connection 객체를 유지할 수 있다.

public class ConnectionDispenser {
    private static class ThreadLocalConnection extends ThreadLocal {
        public Object initialValue() {
            return DriverManager.getConnection(ConfigurationSingleton.getDbUrl());
        }
    }

    private static ThreadLocalConnection conn = new ThreadLocalConnection();

    public static Connection getConnection() {
        return (Connection) conn.get();
    }
}

물론 풀링(pooling)을 사용하여 공유 접근을 관리 할 수 있지만 even pooling has some potential drawbacks from a scalability perspective. Because pool implementations must synchronize to maintain the integrity of the pool data structures, if all threads are using the same pool, program performance may suffer due to contention in a system with many threads accessing the pool frequently.(많은 쓰레드들이 풀에 자주 접근하면 지연 문제가 발생할 수 있다는 단점이 있다.)

Using ThreadLocal to simplify debug logging

멀티 쓰레드 환경에서의 각 쓰레드 당 로깅 메시지를 남기고 가져오는 일을 하는 애플리케이션을 작성할 때도 유용하다.

ThreadLocal is also useful in servlet-based applications or any multithreaded server application in which the unit of work is an entire request, because then a single thread will be used during the entire course of handling the request. You can use ThreadLocal variables to store any sort of per-request context information using the per-thread-singleton technique described earlier.

위의 영어 문단이 오늘 ThreadLocal을 공부하게 된 계기 입니다. Acegi를 공부하다 보니 ThreadLocal이 자주 등장합니다. 따라서 이 부분에 대한 이해가 필요했는데 원한 만큼 건진 것 같습니다. 하지만 조금만 더 건져보죠. 재밌으니까요.

ThreadLocal's less thread-safe cousin, InheritableThreadLocal

ThreadLoacl의 친척 뻘인 InheritableThreadLocal이 있다. 이 녀석은 부모 쓰레드에서 자식 쓰레드를 만들 때 InheritableThreadLocal 객체에 부모에 해당하는 데이터가 있다면 그것을 자식에게도 물려 주는 특징이 있습니다. 이때 Thread-safe를 유지하려면 immutabl(한번 만들면 변하지 않는)한 데이터만을 InheritableThreadLocal 넣어 두어야 합니다.

ThreadLocal performance

1.2에 처음 만들어 지고 1.3에 많은 개선(원문 참조)이 있었지만 성능이 많이 떨어졌고, 1.4에서 조금 나아졌다.

ThreadLocal should be faster than other techniques such as pooling. Because it is simpler and often less error-prone than those other techniques, it will eventually be discovered as an effective way to prevent undesired interactions between threads.

5.0와 6.0에서는 어떻게 됐을까요?? 모르겠습니다. 아시는 분은 댓글을...;;

The benefits of ThreadLocal

1. It is often the easiest way to render a stateful class thread-safe
2. encapsulate non-thread-safe classes so that they can safely be used in multithreaded environments
3. allows us to bypass the complexity of determining when to synchronize in order to achieve thread-safety
4. it improves scalability because it doesn't require any synchronization
5. 기타 등등등..





'Java' 카테고리의 다른 글

Java에서 URL 다루기 2  (2) 2007.09.26
Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
Factory Method vs Constructor  (0) 2007.05.18
효율적인 문자열 연결 방법  (2) 2007.05.18
Collection과 Thread 3  (4) 2007.05.02
top

  1. Favicon of http://crosscutter.info BlogIcon entworks 2007.08.10 16:07 PERM. MOD/DEL REPLY

    ThreadLocal 정말 좋죠 ^^

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.08.10 16:24 신고 PERM MOD/DEL

    넹. 진작에 알았으면 더 좋았을텐데요. ^^;

  2. Favicon of http://rollin.egloos.com BlogIcon 굴돌 2008.11.04 20:13 PERM. MOD/DEL REPLY

    http://www.javalobby.org/articles/thread-safe/index.jsp
    이 글에서는 5버전 올라오면서부터 쓸만한 성능을 보인다고 하네요 ^^
    이 글의 신뢰성이 얼마나 되는지는 알 수 없지만요..;;
    글 잘 보았습니다. 고맙습니다 :)

    Favicon of http://whiteship.tistory.com BlogIcon 기선 2008.11.04 22:30 PERM MOD/DEL

    우와 꼭 읽어야 할 글이로군요.
    잘 보겠습니다. 썡큐요~ :)

Write a comment.


ThreadLocal

Java : 2007.08.10 13:29


매우 간단하게.. '쓰레드 당 데이터 저장소' 라고 할 수 있겠습니다.

즉, 각각의 Thread에서 사용하는 객체들을 저장해둔 곳으로 이해할 수 있습니다. 먼저 어떻게 생겼는지 살펴보겠습니다.
사용자 삽입 이미지

딱 네 개의 메소드로 구성되어 있습니다. 이 중에서 remove()는 1.5부터 추가 되었고 나머지는 1.2부터 있었습니다.

get()은 현재 쓰레드가 사용하는 변수의 값을 가져오고,
set(T value)는 현재 쓰레드가 사용하고 있는 변수의 복사본을 저장해 둡니다.
initialValue()는 get()을 호출 했을 때, 해당 쓰레드에 대해 저장되어 있는 값이 없을 때 호출이 되며, 보통은 쓰레드에서 딱 한번만 호출이 되지만 remove()를 호출한 다음 get()을 할 경우 여러번 호출 될 수도 있습니다.

아직도 잘 이해가 가지 않습니다. 지금 여기까지 봐서는 Collection 스러운 분위기만 풍길 뿐 뭔지 모르겠습니다. 그래서 구현된 클래스를 살펴보겠습니다.

public class ThreadLocal<T> {
    ...
    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
    }

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

    public void remove() {
         ThreadLocalMap m = getMap(Thread.currentThread());
         if (m != null)
             m.remove(this);
     }

    protected T initialValue() {
        return null;
    }
    ...
}

사용자 삽입 이미지
내부적으로 ThreadLocalMap 이라는 static inner 클래스를 사용하고 있습니다. 이 Map을 사용하여 각 Thread 당 데이터를 저장하고 그곳에서 데이터를 주는 일을 하고 있습니다. 더 자세히 살펴보기는;; 무리라서 일단 여기에서 잠시 쉬었다 가겠습니다.

'Java' 카테고리의 다른 글

Java에서 URL 다루기 1  (0) 2007.09.18
자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
Autoboxing의 오묘함  (2) 2007.09.09
객체 크기 구하기  (2) 2007.08.14
때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
ThreadLocal  (0) 2007.08.10
JMX  (0) 2007.06.06
Factory Method vs Constructor  (0) 2007.05.18
효율적인 문자열 연결 방법  (2) 2007.05.18
Collection과 Thread 3  (4) 2007.05.02
Collection의 Fail-fast  (0) 2007.05.01
top

Write a comment.


JMX

Java : 2007.06.06 10:12


참조 :
http://java.sun.com/developer/technicalArticles/J2SE/jmx.html
http://java.sun.com/j2se/1.5.0/docs/guide/jmx/overview/intro.html
http://kr.sun.com/developers/techtips/e2005_0222.html

JMX가 무슨 기술인가?
The JMX specification defines an architecture, the design patterns, the APIs, and the services for application and network management and monitoring in the Java programming language
자바 애플리케이션과 네트워크를 관리/모니터링 할 수 있는 서비스

JMX로 무엇을 할 수 있는가?
  • Consulting and changing application configuration
  • Collecting statistics about application behavior and making the statistics available
  • Notification of state changes and erroneous conditions
  • JMX를 왜 사용하나?
    JMX technology provides Java developers across all industries with a flexible means to instrument Java code, create smart Java agents, implement distributed management middleware and managers, and smoothly integrate these solutions into existing management and monitoring systems.
    JMX를 사용하면
    자바 코드를 더 유연하게 다룰 수 있고(?)
    똑똑한 자바 에이전트를 만들 수 있고
    분산된 관리 미들웨어와 도구를 구현할 수 있으며
    이러한 솔루션을 기존의 관리/모니터링 시스템과 부드럽게 통합할 수 있다.

    'Java' 카테고리의 다른 글

    자바 네트워크 프로그래밍 기초 지식  (0) 2007.09.17
    Autoboxing의 오묘함  (2) 2007.09.09
    객체 크기 구하기  (2) 2007.08.14
    때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
    ThreadLocal  (0) 2007.08.10
    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    top

    Write a comment.


    Factory Method vs Constructor

    Java : 2007.05.18 14:43


    참조 : Effective Java Chapter 2 Item 1

    여러개의 생성자 대신 Static Factory 메소드를 제공하면 다음과 같은 장점이 있습니다.

    장점: 이름을 가지고 있다.

    Java API 중 BigInteger의 생성자 중에 BigInteger(int bitLength, int certainty, Random rnd) 이런 녀석이 있습니다.
    과연 이 생성자가 무슨 일을 하는지 예측할 수 있나요? 없죠.
    그럼 이 생성자와 동일한 역할을 하면서 Java 1.4에 추가된 Static Factory 메소드인 static BigInteger probablePrime(int bitLength, Random rnd) 이 메소드는 어떤가요? 이번엔 무슨 일을 하는지 알 수 있지 않나요? 소수를 반환합니다.

    이렇게 Java는 생성자의 이름이 클레스 이름과 동일해야 한다는 규칙 때문에 명확히 무슨 일을 하는 생성자인지 표현하지 못합니다.
    이런 단점을 보완할 때 Static Factory 메소드를 사용할 수 있겠습니다.

    장점: 생성자와는 달리 매번 새로운 객체를 생성하지 않아도 됩니다.

    생성자를 사용하면 매번 새로운 객체를 반환받게 됩니다.
    만약 같은 객체를 자주 여러 곳에서 사용해야 한다면 미리 만들어 둔 객체를 factory에서 반환 해주기만 하면 되겠죠.

    public StaticFactoryExam {

    private StaticFactoryExam exam = new StaticFactroyExam();

    public static StaticFactoryExam getExam(){
    return exam;
    }

    }

    매우 간단하게 구현하다면 위와 같은 모습을 같은 객체를 계속 반환 할 수 있습니다.
    매번 객체를 생성하지 않아도 되기 때문에 성능향상의 장점이 생깁니다.

    Immutable 클레스와 싱글톤 객체를 다룰 때 자주 사용합니다.

    장점: 생성자와는 달리 리턴 타입이 자유롭습니다.

    생성자는 무조건 자신의 타입의 객체를 반환하지만 메소드에는 그러한 제한이 없습니다. 따라서 해당 클레스의 하위 타입을 반환해도 됩니다.
    이런 특징을 잘 살리면 훨씬 유연한 API를 만들 수 있습니다.
    Collections의 팩토리 메소드들을 생각해 보시면 될 것 같습니다.

    단점: 다른 정적 팩토리 메소드와 구분이 안 됩니다.

    생성자 처럼 API에서 눈에 띄는 위치에 있는 것도 아니기 때문에 다른 메소드들과 구분하는게 쉽지 않습니다.
    이 문제는 컨벤션을 잘 적용하면 어느정도 해결할 수 있습니다.
    예) getInstance(), valueOf()

    'Java' 카테고리의 다른 글

    Autoboxing의 오묘함  (2) 2007.09.09
    객체 크기 구하기  (2) 2007.08.14
    때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
    ThreadLocal  (0) 2007.08.10
    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    top

    Write a comment.


    효율적인 문자열 연결 방법

    Java : 2007.05.18 14:21


    자바에서 문자열을 연결하는 방법을 살펴보고 각각의 효율성을 비교해 봅니다.

    문자열을 연결하는 방법
    1. + 연산자 이용
    2. String 클레스의 concat 메소드 사용
    3. StringBuffer의 append 사용
    4. StringBuilder의 append 사용

    네가지 경우에 대해 테스트를 작성합니다.
    public class ConcatTest {

        private String s1;
        private String s2;

        @Before
        public void setUp(){
            s1 = "Hibernate";
            s2 = "Spring";
        }

        @Test
        public void plusOperator() {
            Long start = Calendar.getInstance().getTimeInMillis();

            for(int i = 0 ; i < 5000 ; i++){
                s1 = s1 + s2;
            }

            Long end = Calendar.getInstance().getTimeInMillis();

            System.out.println("Operator : " + (end - start));
        }

        @Test
        public void concatMethod() {
            Long start = Calendar.getInstance().getTimeInMillis();

            for(int i = 0 ; i < 5000 ; i++){
                s1 = s1.concat(s2);
            }

            Long end = Calendar.getInstance().getTimeInMillis();

            System.out.println("ConcatMethod : " + (end - start));
        }

        @Test
        public void stringBuffer() {
            Long start = Calendar.getInstance().getTimeInMillis();

            StringBuffer buffer1 = new StringBuffer(s1);
            StringBuffer buffer2 = new StringBuffer(s2);

            for(int i = 0 ; i < 5000 ; i++){
                buffer1.append(buffer2);
            }

            String result = buffer1.toString();

            Long end = Calendar.getInstance().getTimeInMillis();
            System.out.println("StringBuffer : " + (end - start));
        }

        @Test
        public void stringBuilder() {
            Long start = Calendar.getInstance().getTimeInMillis();

            StringBuilder builder1 = new StringBuilder(s1);
            StringBuilder builder2 = new StringBuilder(s2);

            for(int i = 0 ; i < 5000 ; i++){
                builder1.append(builder2);
            }

            String result = builder1.toString();

            Long end = Calendar.getInstance().getTimeInMillis();
            System.out.println("StringBuilder : " + (end - start));
        }

    }

    결과는 다음과 같습니다.
    Operator : 1078
    ConcatMethod : 500
    StringBuffer : 15
    StringBuilder : 0

    Operator : 1062
    ConcatMethod : 438
    StringBuffer : 0
    StringBuilder : 15

    Operator : 1532
    ConcatMethod : 453
    StringBuffer : 0
    StringBuilder : 16

    Operator : 1172
    ConcatMethod : 453
    StringBuffer : 0
    StringBuilder : 16

    Operator : 1281
    ConcatMethod : 453
    StringBuffer : 16
    StringBuilder : 16

    Operator : 1171
    ConcatMethod : 500
    StringBuffer : 0
    StringBuilder : 0

    Operator : 1187
    ConcatMethod : 454
    StringBuffer : 0
    StringBuilder : 16

    흠.. 이상하네요. 예전에 영회형이 간단하게 정리 했었던 글과 정반대의 결과가 나왔습니다.
    테스트는 Java 6.0을 사용했습니다.

    StringBuffer와 StringBuilder 가 String 클레스에 있는 concat 메소드나 연산자에 비해 엄청나게 빠른것을 확인할 수 있습니다.

    원인은 String의 immutable한 특징 때문입니다. API를 보시면 concat 메소드에 다음과 같이 적혀 있습니다.
    If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string.

    즉 매번 새로운 String 객체를 만들게 되기 때문에 추가적인 비용이 많이 발생하는 것 같습니다. 하지만 그렇다 하더라도.. + 연산자 사용하는 것 보단 훨씬 낳습니다.

    s1 = s1 + s2; 라는 한 문장이 두 개의 연산(더하기 연산과 대입 연산)을 포함하고 있기 때문에 저런 결과가 나왔다고 생각됩니다. 그렇다고 s1 + s2; 이렇게 표현할 수도 없고(컴파일에러) 참 난감하네요. :)

    결론은 String이 Immutable한 특징 때문에 StringBuilder나 StringBuffer를 사용하여 문자열을 이어 붙이는 것이 String 객체를 그냥 사용하는 것 보다 굉장히 효율적이라는 것입니다.


    'Java' 카테고리의 다른 글

    객체 크기 구하기  (2) 2007.08.14
    때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
    ThreadLocal  (0) 2007.08.10
    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    top

    1. 노류장화 2007.07.04 11:28 PERM. MOD/DEL REPLY

      StringBuffer / StringBuilder 실행순서를 바꿔보시고 실행해보세요.

      Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.07.04 11:40 PERM MOD/DEL

      버퍼와 빌더의 실행에 순서가 있지 않습니다. 각각이 독립적인 테스트 케이스이기 때문에 테스트 메소드 순서가 결과에 영향을 주지는 않습니다.

    Write a comment.


    Collection과 Thread 3

    Java : 2007.05.02 20:37


    이전 글인 "Collection과 Thread 2"에서 공부할 것으로 분류했던 클레스들의 정체를 밝히는 것으로 본 시리즈의 막을 내리려고 합니다.

    총정리 및 발표는 이번주 AJN 정모에서 하게 됩니다. 혹시라도 차후 Agile Java 3기에 참여하실 분들 중에서 관심있으신 분들께서는 이메일 주소 남겨주시면 특별히 무료로 이번 정모에 참석하실 수 있도록 안내 메일 보내 드리겠습니다.

    그럼 다시 본론으로 돌아가서 Java 5.0에서 Concurrent Collection이라는 것들을 추가했습니다. 그것들이 바로 이전 글에서 잘 모르겠다고 했던 클래스들입니다.

    Concurrent Collections

    CopyOnWriteArrayList

    ConcurrentSkipListSet, CopyOnWriteArraySet

    ConcurrentLinkedQueue

    ConcurrentHashMap, ConcurrentSkipListMap


    이녀석들이죠. 기존에 존재하던 Syncronized Collection을 사용하면 모든 메소드들이 전부 키를 사용하여 롹킹되기 때문에 완전한 Thread-Safety는 보장이 되지만 그에 따른 비용이 발생하게 됩니다. 데드락이 발생할 수 있는 여지가 생기며, 여러 쓰레드가 대기 상태에 머무를 수 있습니다.

    하지만 Concurrent Collection은 멀티 쓰레드 환경에서 하나의 데이터에 여러 쓰레드가 동시에 읽는 것을 허용하면서도 쓰기 작업은 하나의 쓰레드만 하도록 롹킹을 Fine-grained하게 적용했습니다. 따라서 기존의 Syncronized Collection에 비해 퍼포먼스가 좋을 것이며 주된 차이점으로는 iteration할 때 fail-fast가 발생하지 않는 다는 것입니다.

    ConcurrentHashMap 은 동기화 된 Map 구현체를 대체 하기 위해 만들어졌습니다.
    ConcurrentSkipListMap 은 동기화 된 SortedMap 을 대체 하기 위해 Java 6.0 에 추가 됐습니다.
    CopyOnWriteArrayList 는 동기화 된 List 구현체를 대체 하기 위해 만들어졌습니다.
    ConcurrentSkipListSet 는 동기화 된 SortedSet 을 대체 하기 위해 Java 6.0 에 추가 됐습니다.
    CopyOnWriteArraySet 는 동기화 된 Set 구현체를 대체 하기 위해 만들어졌습니다.
    ConcurrentLinkedQueue 는 동기화 된 Queue 구현체를 대체 하기 위해 만들어졌습니다.

    ConcurrentHashMap 살펴보기

    위에서 언급했다시피 모든 메소드에 롹킹을 하는 Syncronized Collection과는 다르게 읽기 작업을 하는 메소드는 롹킹을 걸지 않고 쓰기 작업을 하는 메소드에 롹킹을 걸어서 특정 수의 쓰기 작업한 동시적으로 처리할 수 있도록 합니다.

    또한 ConcurrentModificationException을 발생시키지 않습니다. 콜렉션이 수시로 변할 수 있다는 가정하에 Fail-fast 검증 방식을 사용하지 않는 것입니다. 어차피 멀티 쓰레드 상황이면 당연히 수시로 변할 수 있다는 가정을 가지고 간다면 타당한 예외 처리 방법이기도 합니다.

    장점만 있는 것은 아닙니다. 콜렉션이 수시로 변할 수 있다는 가정하에 동기화(weakly consistent)를 제공하고 있기 때문에 size 나 isEmpty 메소드의 정확함을 보장하지 못합니다.

    또 다른 단점으로는 exclusive access(상호배제) 를 제공하지 못합니다. 상호배제는 운영체제 시간에 들었던 것으로 멀티프로세스에 관한 이야기에서 나온 것인데 고스란히 쓰레드에도 적용할 수 있겠습니다. 즉 여러 쓰레드가 하나의 공유자원에 접근하고자 할 때 하나의 쓰레드가 공유자원에 접근하여 작업하는 중에는 다른 모든 쓰레드는 중단된 상태여야 하는데 이것을 상호배제라고 합니다.(그걸 구현한 방법중 하나가 key를 사용한 locking이고 모니터랑 세마포어 같은 것들도 있습니다.)

    상호배제를 사용하지 못하는 단점을 보완할 수 있는 인터페이스를 제공합니다. 바로 ConcurrentMap 인터페이로서 put-if-absent, remove-if equal, replace-if-equal 같은 메소드를 제공합니다.

    사용자 삽입 이미지

    이 클레스와 같은 원리로 다른 ConcurrencyXXX 클레스들도 똑같이 동작합니다.

    CopyOnWriteArrayList 살펴보기

    동기화 된 List 구현체들 대신으로 사용할 수 있으며 iteration 할 때 콜렉션을 복사 하거나 메소드들에 롹을 걸 필요를 없애주면서 동시성을 제공하는 클레스입니다.

    콜렉션에 쓰기 작업을 Thread-safety를 보장하기 위해 매번 수정된 콜렉션의 복사체를 제공하여 해결합니다. 따라서 ConcurrencyModificationException을 발생시키지 않으며(snapshop을 사용하기 때문이죠.), iteration을 하는 모든 쓰레드는 동기화 할 필요가 없으며 복사체를 가질 순간의 콜렉션의 상태를 기반으로 정확하게 동작하게 됩니다.

    하지만 콜렉션이 수정 될 때 마다 복사하는 비용이 발생하며 특히 덩치가 큰 콜렉션의 경유 콜렉션에 수정하는 작업보다 iteration하는 작업이 많을 때 이 클레스의 사용이 적당하겠습니다.

    이 클레스와 같은 원리로 CopyOnWriteArraySet 클레스도 똑같이 동작합니다.

    'Java' 카테고리의 다른 글

    때로는 공유하지 않는 것이 최선일 수 있다.(by ThreadLocal)  (4) 2007.08.10
    ThreadLocal  (0) 2007.08.10
    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    top

    1. 2009.04.16 10:35 PERM. MOD/DEL REPLY

      비밀댓글입니다

      Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.04.16 11:26 신고 PERM MOD/DEL

      넵 오타 수정하겠습니다.
      굳이 비밀글로 안하셔도 될텐데 깜짝놀랬네요.ㅋㅋ

    2. 이호연 2009.11.03 14:13 PERM. MOD/DEL REPLY

      스프링 전문가인줄 알았는데, 자바 기초부터 하이버네이트 등 여러 세세한 부분까지 기록을 남겨놓으셨군요. 대단합니다.

      포스트를 읽다가 한가지 제가 알고 있던 내용이랑 조금 다른 내용이 있는 것 같아서 살짝 태클 겁니다.-_-;;
      Effective java - second edition, Item 70을 보면,
      Thread-safety 에 대한 레벨이 나오는데,
      Concurrent Collection 는 unconditionally thread-safe 하고
      Collections.synchronizedXXX 는 conditionally thread-safe 하다고 합니다. iterator는 외부적으로 synchronized로 감싸야 한다고 하는데요.
      Synchronized Collections가 완전한 Thread-safety를 보장한다는 건 내용이 조금 다르지 않나해서요... 제가 잘못 이해한 것인지 모르겠네요.^^;;;

      오래전에 올리신 글 같은데 대단하네요...
      기선씨 덕분에 자극받고 더욱 열심히 공부해야겠습니다^^
      수고하세요^^

      Favicon of https://whiteship.tistory.com BlogIcon 기선 2009.10.31 18:33 신고 PERM MOD/DEL

      와.. 감사합니다.
      알려주신 내용 확인해보고 게시물을 수정하곘습니다.
      ㅎㅎ 이런글은 오픈해주셔도 되는데 말이죠~

    Write a comment.


    Collection의 Fail-fast

    Java : 2007.05.01 12:42


    참조 : Fail-fast Iterator에 대한 멀티쓰레드 무결성 해결방법

    Fail-fast란? Fail-fast vs. complete validation

    Collection Iteration에서의 Fail-fast

    맨 위에 있는 참조 링크를 참조하시면 알 수 있지만 Iterator는 Enumeration과 달리 snapshot을 사용하지 않고 해당 콜렉션 자체에 대한 링크를 사용하여 traversal 하기 때문에 콜렉션이 변하게 되면 자신이 현재 참조 하고 있는 콜렉션에 대한 view가 correctness가 보장되지 않기 때문에 fail-fast하게 됩니다.

    Iterator가 Fail-fast 하는 원리

    modification number라는 것을 사용하여 view하고 있는 콜렉션에 대한 수정(새로운 요소 추가 or 기존 요소 변경 삭제)이 일어나면 modification number가 변합니다.
    매번 다음 요소를 view하기 전에 이 넘버를 체크 하고 처음에 시작할 때의 number와 다르면 concurrrentModificationExceptioin이 발생합니다.
    참조 : ConcurrentModificationException 살펴보기

    iterator의 Fail-fast 방지하기


    Fail-fast자체를 원천 봉쇄 하는 방법은 때에 따라 적절한 행동이 아닐 수도 있습니다. 하지만 멀티 쓰레드 환경에서 그다지 원하는 상황은 아닐 것 입니다. 하나의 쓰레드는 리스트를 쭉 훑어 보고 싶고 하나의 쓰레드는 리스트에서 하나를 제거 하고 싶습니다. 둘 이 따로따로 동작하면 아무런 문제가 생기지 않지만 하필이면!!! 리스트를 훝어보던 쓰레드가 잠깐 멈추고 그 사이 다른 쓰레드가 리스트에서 하나를 제거하면 Fail-fast가 발생하고 ConcurrentModificationException이 발생합니다. 이걸 방지하는 방법으로 제가 알고 있는 방법은 두 개.
    1. 루프를 동기화 시키기.
    2. Snapshot 이용하기.
    3. 동기화 된 콜렉션 사용하기.

    동기화 된 콜렉션 사용하기.

    이 방법에 선을 그어 놓은 것은 Fail-fast를 방지 하지 못하기 때문입니다. 동기화 된 콜렉션으로는 이 전글 Collection와 Thread 1, Collection와 Thread 2에서 확인할 수 있습니다. 이 콜렉션이 사용하는 iterator 메소드를 살펴보면 다음과 같이 주석이 달려있습니다.

    사용자 삽입 이미지

    루프를 동기화 시키기.

    리스트를 view하는 iteration 과정을 콜렉션의 lock을 사용하여 동기화 시킵니다. 그럼 위의 경우에 하나의 쓰레드가 해당 이터레이션을 하고 있을 때 다른 쓰레드는 리스트에 대한 접근이 막히게 됩니다.
    사용자 삽입 이미지
    단점은 이터레이션이 길어지면 락이 걸리는 기간이 길어지기 때문에 동기화의 여러 단점들(데드락, 컨텍스트 스위칭 비용)이 발생할 수 있는 여지가 많아집니다.

    Snapshot 이용하기.

    해당 콜렉션을 복사해서 보는 방법입니다. 복사 비용이 발생한다는 단점이 있지만 확실하게 Fail-fast가 방지 됩니다. 그리고 위에서 살펴본 루프를 동기화 시킬 때 발생하는 동기화 문제를 방지 할 수 있습니다. Snapshot을 사용하는 방법은 다음에 더 살펴보도록 하겠습니다.

    'Java' 카테고리의 다른 글

    ThreadLocal  (0) 2007.08.10
    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    top

    Write a comment.


    숨어있는 Iterator 찾기

    Java : 2007.05.01 00:56


    다음의 코드 중에 iterator가 숨어있는 곳을 찾아 주세요~

    class HiddenIterator {

           private final Set<Integer> set = new HashSet<Integer>();

           public synchronized void add(Integer i) {

                 set.add(i);

           }

           public synchronized void remove(Integer i) {

                 set.remove(i);

           }

           public void addTenThings() {

                 Random r = new Random();

                 for (int i = 0; i < 10; i++)

                        add(r.nextInt());

                 System.out.println("DEBUG: added ten elements to " + set);

           }

    }

    정답 및 해설은 이번 주 일요일 AJN 정모에서...

    'Java' 카테고리의 다른 글

    JMX  (0) 2007.06.06
    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    top

    Write a comment.


    Reflections on Java Reflection

    Java : 2007.04.25 23:05


    원문 : http://www.onjava.com/pub/a/onjava/2007/03/15/reflections-on-java-reflection.html

    번역 : 했지만 나중에 한빛에 올라올 듯...

    후기 : 저자가 글을 상당히 쉽고 재치있게 썼습니다. 제목부터가 심상치 않죠. 하지만 내용을 정말 재밌고 흥미롭게 써서 쉽게 리플렉션에 친해질 수 있는 글입니다. 제목을 "Java 리플렉션에 대한 재고(reflection)" 라고 붙였는데.. 괜찮은지 모르겠네요. 생소한 내용을 이렇게 잘 설명해주는 글을 쓸 수 있다니 저자가 부러웠습니다.

    'Java' 카테고리의 다른 글

    Factory Method vs Constructor  (0) 2007.05.18
    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    top

    1. Favicon of http://seal.tistory.com BlogIcon 물개 2007.04.26 09:07 PERM. MOD/DEL REPLY

      멋져.. 한빛에 글 올라오면 번역감수 해주지. 캬캬..

      Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.04.26 10:44 PERM MOD/DEL

      한빛에는 거의 2~3주 후에 올라오더군요.
      그전에 워드 파일로 보내드릴께요. :)

    Write a comment.


    Collection과 Thread 2

    Java : 2007.04.24 18:07


    Thread Safe 하냐 안하냐 기준으로 Collection 클레스들을 나눠 봤습니다. Java 6.0 API 기준으로 나눴기 때문에 새로 눈에 띄는 클레스들과 잘 모르겠는 클레스들도 포함되어 있습니다.

    Thread safe collections

    Vector(Stack)

    HashTable

    BlockingQueue implementations(ArrayBlockingQueue, DelayQueue, LinkedBlockingDeque, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue)

    BlockingDeque implementation (LinkedBlockingDeque)

     

    Not thread safe collections

    LinkedList, ArrayList(AttributeList, RoleList, RoleUnresolvedList)

    EnumSet, HashSet, TreeSet

    ArrayDeque, PriorityQueue

    EnumMap, HashMap, IdentityHashMap, TreeMap, WeakHashMap

     

    뭔가 이상한 것들(공부해야 할 것들)

    CopyOnWriteArrayList

    ConcurrentSkipListSet, CopyOnWriteArraySet

    ConcurrentLinkedQueue

    ConcurrentHashMap, ConcurrentSkipListMap


    흠.. 대체 CopyOnWrite 와 Concurrency, ConcurrencySkip 은 어떤 뜻일까요? 역시 다음 글에서 알아보도록 하겠습니다.

    'Java' 카테고리의 다른 글

    효율적인 문자열 연결 방법  (2) 2007.05.18
    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    top

    Write a comment.


    Collection과 Thread 1

    Java : 2007.04.24 16:15


    사용자 삽입 이미지
    출처 : http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html

    Java 6 API에서 Collection을 살펴 보면 다음과 같은 문구가 있습니다.
    It is up to each collection to determine its own synchronization policy.
    Collection의 상위 레벨에서 thread와 관련된 정책은 없고 동기화에 대한 책임은 각각의 구현체들마다 다를 수 있다는 것을 알려줍니다.

    Collection 인터페이스를 구현한 클래스들은 다음과 같습니다.
    AbstractCollection, AbstractList, AbstractQueue, AbstractSequentialList, AbstractSet, ArrayBlockingQueue, ArrayDeque, ArrayList, AttributeList, BeanContextServicesSupport, BeanContextSupport, ConcurrentLinkedQueue, ConcurrentSkipListSet, CopyOnWriteArrayList, CopyOnWriteArraySet, DelayQueue, EnumSet, HashSet, JobStateReasons, LinkedBlockingDeque, LinkedBlockingQueue, LinkedHashSet, LinkedList, PriorityBlockingQueue, PriorityQueue, RoleList, RoleUnresolvedList, Stack, SynchronousQueue, TreeSet, Vector
    그럼 과연 이중에서 어떤 클래스들은 Thread-safe 할까요? 그건 다음 포스팅에서 살펴보겠습니다.

    'Java' 카테고리의 다른 글

    Collection과 Thread 3  (4) 2007.05.02
    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    top

    Write a comment.


    Thread와 Collection 관련 링크 모음

    Java : 2007.04.19 11:57


    Java Thread Performance: Collection Test
    Java 1.5 (5.0) new feature: collection and thread
    Making a Thread-Safe or Synchronized Collection
    Concurrent collections classes
    Iterator 관련 메모

    'Java' 카테고리의 다른 글

    Collection의 Fail-fast  (0) 2007.05.01
    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    top

    Write a comment.


    예제로 살펴보는 쓰레드 제어하기

    Java : 2007.04.10 20:53


    원문 : Controlling Threads by Example (http://www.onjava.com/pub/a/onjava/2007/04/06/controlling-threads-by-example.html)

    번역 :
    예제로 살표보는 쓰레드 제어하기 - (1)
    예제로 살표보는 쓰레드 제어하기 - (2)

    'Java' 카테고리의 다른 글

    숨어있는 Iterator 찾기  (0) 2007.05.01
    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
    top

    Write a comment.


    Java 6.0의 Collection

    Java : 2007.03.22 08:44


    원문 : What is new in Java 6.0 Collections API?
    번역 : Java 6.0 컬렉션 API에 어떤 변화가 있는가?


    'Java' 카테고리의 다른 글

    Reflections on Java Reflection  (2) 2007.04.25
    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
    GC관련 아티클  (0) 2007.01.19
    top

    1. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.03.22 09:37 PERM. MOD/DEL REPLY

      오~번역 탄력 받으셨군요 ~
      나는 언제하지 >.<

      Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.03.22 10:22 PERM MOD/DEL

      난 주로 수업시간에 하지 ㅋㅋ
      경영혁신, 분산시스템.. 이 두 섭시간에 보통 책을 보든지 번역을 하면 되는거지

    2. Favicon of http://epro.tistory.com BlogIcon epro 2007.03.22 21:10 PERM. MOD/DEL REPLY

      오.. 깔끔한 번역..
      찬욱님과 기선님의 부지런함은 따라잡을 수 없군요.. ㅎㅎ

      Favicon of http://whiteship.tistory.com BlogIcon 기선 2007.03.22 23:44 PERM MOD/DEL

      찬욱이나 대엽씨에 비하면 전 새발의 피죠.ㅋㅋ
      http://network.hanbitbook.co.kr/view.php?bi_id=1343
      http://network.hanbitbook.co.kr/view.php?bi_id=1345

    Write a comment.


    private에 대한 착각

    Java : 2007.03.05 23:37


    public class Point {

        private int x;

        private int y;

        public Point() { }

        public Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public Point(Point aPoint) {
            x = aPoint.x;
            y = aPoint.y;
        }
    }
    빨간 부분 과 파란 부분을 잘 보시면 에러가 보이시나요?

    ...

    안보이는게 정상입니다. 저는 저 코드가 왜 에러가 나지 않지? 라며 한참을 보다가.. 아차.. 내가 너무 getter() setter()에 중독되어 있었구나 라는 생각에 도달 하게 되었습니다.

    private은 자기 자신 class 안에서만 사용할 수 있는 것이지 자기 자신 객체 안에서만 사용할 수 있는 것이 아닙니다.

    제가 착각하고 있었던 것 만큼 private은 쪼잔하지 않았습니다. 미안해 private.. 자바 공부 다시 할께~

    'Java' 카테고리의 다른 글

    Collection과 Thread 2  (0) 2007.04.24
    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
    GC관련 아티클  (0) 2007.01.19
    Generics 번외 - 겉모습만 보곤 알 수 없슴.  (2) 2007.01.17
    top

    TAG private
    1. Favicon of http://chanwook.tistory.com BlogIcon 찬욱 2007.03.06 00:36 PERM. MOD/DEL REPLY

      저도 속았어요..ㅎ
      미안해 자바야 -0-;

      Favicon of https://whiteship.tistory.com BlogIcon 기선 2007.03.06 00:41 신고 PERM MOD/DEL

      ㅋㅋㅋ나만 그런게 아니라 어째 위안이 되는군~ 내일 봅시다. 졸리네;

    Write a comment.


    Stream 인코딩 바꾸기

    Java : 2007.02.28 00:19


    제 블로그 RSS URL을 날리면 어떤 HTML이 날아오는지 보고 싶습니다.

    String request - "http://whiteship.tistory.com";
    URL url = new URL(request);
    HttpURLConnection connection = (HttpURLConnection)url.openConnection();

    이렇게 커넥션 객체를 생성한 다음에.. 이 커넥션에서 다시 InputStream을 얻어서 다시 아래 처럼 InputStreamReader로 그리고 이걸 다시 버퍼를 사용해서 읽을 수 있도록 BufferedReader에 연결 시킵니다.[각주:1]

    BufferedReader br = BufferedReader(new InputStreamReader(connection.getInputStream()));

    그리고 이후에는 br.readLine() 으로 한줄씩 읽어서 StringBuilder에 쌓아 뒀다가 출력해보면 됩니다.

    그렇게 해봤습니다.
    이상한 글씨들이 콘솔창에 출력됩니다. OTL..

    인코딩 문제인데 구글신에게 물어보니까 InputStreamReader의 생성자를 이용해서 인코딩을 바꿀 수 있다고 합니다. 현재 인코딩을 찍어보니까[각주:2] MS949라고 출력됩니다.

    RSS나 기타 오픈API를 사용한 결과물은 UTF-8을 사용한다고 합니다. 그리고 InputStreamReader의 생성자를 보니까 다음과 같이 네개의 생성자가 있었습니다.
    사용자 삽입 이미지

    이 중에서 제일 아래 녀석을 사용해서 다음과 같이 수정해 줍니다.

    br = BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));

    결과물을 확인해 보니 제대로 출력이 되는 걸 볼 수 있었습니다.

    1. 정말 이 부분은 외워 지지가 않네요. 매번 코드를 찾아보게 되는 부분입니다. [본문으로]
    2. InputStreamReader의 String getEncoding()을 사용하면됩니다. [본문으로]

    'Java' 카테고리의 다른 글

    Collection과 Thread 1  (0) 2007.04.24
    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
    GC관련 아티클  (0) 2007.01.19
    Generics 번외 - 겉모습만 보곤 알 수 없슴.  (2) 2007.01.17
    Generics  (2) 2007.01.17
    top

    Write a comment.


    SWT 프로그램 실행하기

    Java : 2007.02.21 17:48


    참조 : SWT-JFace In Action, SWT Programming with Eclipse

    코드는 아래와 같습니다.
    public class HelloSWT {
        public static void main(String[] args) {

            Display display = new Display();
            Shell shell = new Shell(display);

            Text helloText = new Text(shell, SWT.CENTER);
            helloText.setText("Hello SWT!");
            helloText.pack();

            shell.pack();
            shell.open();
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                    display.sleep();
            }
            display.dispose();

        }
    }

    다른 부분은 거의 템플릿 같고 빨간 부분에 뭔가 만들어 주면 될 것 같습니다.

    실행을 하려면 아.. 먼저 컴파일 에러를 없애려면 swt.jar 파일이 필요합니다. swt.jar 파일은  여기[각주:1] swt_버전.zip 파일을 다운 받으시면 안에 들어 있습니다. swt.jar 파일을 라이브러리에 추가해 줍니다.

    그럼 이제 컴파일 에러는 없어지지만 실행하면 ~~.dll 파일을 못찾겠다고 합니다. 못 찾는 파일은.. zip 파일 안에 들어 있습니다. 그 파일을 현재 프로젝트가 사용중인 JDK or JRE 버젼의 디렉토리 밑에 있는 bin 폴더 안에 복사해서 넣어 주면 됩니다.

    사용자 삽입 이미지

    이런 앙증맞은 화면이 떳군요.

    참조 하면 좋을 것 같은 링크 : http://www.eclipse.org/swt/widgets/
    1. stable 버젼에서 사용하는 OS 종류를 클릭하시면 됩니다. [본문으로]

    'Java' 카테고리의 다른 글

    Thread와 Collection 관련 링크 모음  (0) 2007.04.19
    예제로 살펴보는 쓰레드 제어하기  (0) 2007.04.10
    Java 6.0의 Collection  (4) 2007.03.22
    private에 대한 착각  (2) 2007.03.05
    Stream 인코딩 바꾸기  (0) 2007.02.28
    SWT 프로그램 실행하기  (0) 2007.02.21
    제8회 한국 자바 개발자 컨퍼런스  (2) 2007.01.25
    GC관련 아티클  (0) 2007.01.19
    Generics 번외 - 겉모습만 보곤 알 수 없슴.  (2) 2007.01.17
    Generics  (2) 2007.01.17
    Eclipse 단축키 모음  (6) 2007.01.11
    top

    TAG Eclipse, swt

    Write a comment.




    : 1 : 2 : 3 : 4 : 5 :