본문 바로가기

Programming/JAVA

Thread, 압축 및 배포



//===========================================================================//
  본 내용은 2002년 제가 Java 강의를 수강하며 정리 했던 내용을
    기본으로 하여 정리하였습니다.
  - 마침 java 기초를 전파할 기회가 생겨 핑계김에 정리해 가려 합니다.
  작성자 : litwave
//---------------------------------------------------------------------------//

<목차>

1. 압축 및 배포

3. Thread

//---------------------------------------------------------------------------//


1. 압축 및 배포
    1) 압축 : jar -cvf 파일명.jar 압축시킨 파일들
       해제 : jar -xvf 파일명.jar
    2) doc 파일 생성
      -> javadoc 해당파일.java
    3) 배포
      - 배치파일 만들기 : set path = ~
                          set classpath = ~
                          java 실행 클래스
      - readme.txt

2. 압축 및 배포 실습
    2.1 배포파일 만들기
        1) 배포할 파일(소스파일 제외)을 하나의 폴더에 모아 놓는다.
        2) 배포할 파일의 도움말을 만든다.
            /**              */             사이에 도움말 내용을 적는다.
            - 특정 메소드나 클래스 위에 /** 메소드 정보    */ 과 같이 적는다.
        3) 도움말 폴더를 만들어서 java파일들을 복사한다.
            도움말 폴더에서
                javadoc 파일명.java 
            를 하면 해당 도움말 파일이 Html 파일로 생성된다.
        4) 여기서 del *.java를 해서 java 파일을 지워 준다.

    2.2 실행 파일 만들기
        - 자동으로 실행 될 수 있는 배치파일을 만들어야 한다.
        1) 메모장을 열어서(파일명.bat)을 만들고 아래와 같이 입력한다.
            set path = %path%; c:\java\jdk1.4\bin
            set classpath = classpath%;.
            java 파일명

    2.3 압축을 한다.(-cvf : 생성하면서 파일의 이름을 보여 주겠다. 파일명.jar로 모든 파일이 압축 된다.)
        jar -cvf 파일명.jar *.*

    2.4 압축 파일을 제외하고 모두 지워 준다.
    2.5 압축 파일을 배포할 수 있는 .html 파일을 만든다.
     <a href="파일명.jar"> <h2>가져가세요.. </h2> </a>

    2.6 실행
        1) 파일을 받아 온다.
        2) 압축을 푼다
            jar -xvf 파일명.jar
         - Meta-inf폴더에는 압축 정보가 들어있다.

3. Thread
    - Multi Tasking(다중작업)을 자바에서는 Multi Thread라고 이야기 한다.
    - 지금부터 배울 내용은 하나의 프로세스에서 여러개의 다중 작업을 할 수 있는 것을 배울 것이다.
    - 지금까지는 단일 작업을 수행하는 프로그램을 작성하였다.
    - 하나의 시작에서 하나의 끝으로 가는 것을 Thread 라고 하며, 특히 main에서 시작해서 끝나는 것을 main Thread 라 한다.
    - cpu는 기본적으로 한번에 하나의 job을 수행하게 되고, 여러개의 작업이 Thread에 의해서 동시에 발생하면, cpu 쟁탈전이 벌어지게 된다.
    - 과도한 Thread의 사용은 CPU의 과부하를 발생 시키고 속도 저하를 가져올 수 있다.
    - 멀티 쓰레드는 각각이 단독적인 흐름을 가진다.
    - 쓰레드가 언제 실행 될지는 프로그래머는 알 수가 없다.

  3.1 Thread를 만드는 법
    1Thread 클래스를 상속 받는 방법.(java.lang 에 포함되어 잇음)
      class A extends Thread {
        public void run() {  //Thread를 실행하라고 하면.. 이 메소드 부터 실행이 된다.

        }
      }         //A라는 클래스가 하나의 Thread가 된다.
  
      .
      .
      .
      A ap = new A()
      // ap.run();      //하면 단순히 메소드의 실행만 될 뿐이다. 그래서.. 호출하지 않는다.
      ap.start();       //하면 새로운 작업 흐름을 만들고 그것을 실행 시키라고 알려 주는것이다.
                        //start()는 Thread 객체에 포함된 메소드 이다.


    2Runnable 인터페이스를 상속 받는 방법.
      class A implements Runnable {
        public void run() {    //Runnable 에는 이것 하나의 메소드 밖에 없다.


        }
      }

      A ap = new A();
      Thread tt = new Thread(ap);         // 바로 실행이 안되므로 Thread에 담아서 실행 시켜야 한다.
      tt.start(); 


  3.2 Thread 만들기.
    ->  Ex0129_01.java

    - sleep() : 1/1000초 단위의 시간 간격을 줄 수 있다. // 예외 처리를 해 주어야 한다.
    - 중요 : 쓰레드는 다른 것에 영향을 주지 않으면서 하나의 독립적인 흐름을 만들어 낼 수 있다. 
    - 지금 까지 배운 것은 동시에 여러개의 작업이 실행 될 수 있다는 것을 알려 준것이다.


  3.3 Thread Object
    3.3.1 Field Summary
      MAX_PRIORITY = 10
      MIN_PRIORITY = 1         => 우선 순위 이다.
      NORM PRIORITY = 5 
          -> 숫자가 클수록 CPU 점유시간이 길어진다.
          -> 일반적인 Thread 우선 순위는 5라는 값을 가지게 된다.
    3.3.2 Construct Summary
      Thread 마다 이름을 줄 수 있다. 주지 않으면 자동으로.. thread1 ~ 과같이 숫자가 자동으로 붙는다.

    3.3.3 Method Summary
        - 과제: Thread관련 메소드 모두 예제 만들어 오기..
      1activeCount()     // 활동 중인 쓰레드의 갯수를 돌려 준다
      2currentThread()   // 여러개의 쓰레드가 동작 중일때 현재 쓰레드의 이름을 뽑아 준다.
      3enumerate(Thread[] tarray)      //현재 움직이고 있는 Thread 들을 배열로 담아 준다.
         getName()           // Thread 이름을 얻어 온다.
         getPriority()       // 현재 Thread 우선 순위를 얻어온다.

      4interrupt()         // 특정 Thread 하나를 중지 시키고자 할때..         //Exception 발생 시킴
         interrupted()       // 현재의 Thread가 중지되었는지 아닌지를 돌려줌
         isinterrupted()     // 특정 Thread가 중지 되었는지 중지 되지 않았는지를 돌려줌

         isAlive() // 특정 Thread 가 살아 있는지 확인

      5)isDaemon()           // 현재 쓰레드가 데몬인지 아닌지 체크
        ap.setDaemon(true)   // 데몬 쓰레드로 만들겠다.
        ap.setDaemon(false)  // 독립 쓰레드로 만들겠다.
        - 데몬 쓰레드는 특정 쓰레드에 종속된 쓰레드를 의미 하며, 
          데몬 쓰레드는 메인 쓰레드가 종료되면 같이 종료된다.

      6join()         //특정 쓰레드를 끝까지 수행할때 사용한다.
         join(100);   // 0.1초 동안 지연 시켜 준다.(특정 시간동안만 지연 시킬 수 있다.)

         setPriority()   //우선 순위를 주는 것.
                         //start 하기 전에.. 미리 지정을 해 주어야 한다.
         ap.setPriority(Thread.NORM_PRIORITY+2//형태로 적는 것이 정석
         start()      //run() 을 불러주는 메소드
         yield()      //현재 실행 중인 Thread가 다음 Thread 에게 양보를 해준다.

      7wait()     //특정한 시간을 지정해서 특정시간 동안 대기 시키는 메소드
                    //무한정 대기 상태가 될 수도 있다.
         notify()   //wait 된 Thread를 깨우는 메소드..
         notifyAll()   //Thread와 관련되 모든 것을 깨우는 것.. 

//---------------------------------------------------------------------------//
// 수업 관련 소스
// Ex0129_01.java : Thread 구현 예
class Ex0129_01_Sub /*extends Thread*/ 
                     implements Runnable {
    public void run() {
        
        for(int i = 0; i < 20; i++) {
            for(char ch = 'A'; ch <= 'Z'; ch++) {
                if(ch % 10 == 0) {
                    System.out.print(ch + "\n");
                } else{
                    System.out.print(ch + "\t");
                }
                try {
                    Thread.sleep(50);
                } catch (InterruptedException ee) { }
                
            }
        }
    }
}

public class Ex0129_01 {
    public static void main(String[] ar) {
        System.out.println("Main Thread !!");
        System.out.println("Start !!");
        Ex0129_01_Sub es = new Ex0129_01_Sub();
        Thread tt = new Thread(es);
        tt.start();

        for(int i = 1; i <= 500; i++) {
            if(i % 10 == 0){
                System.out.print(i + "\n");
            } else {
                System.out.print(i + "\t");
            }
            try {
                Thread.sleep(50);
            } catch(InterruptedException ee) { }
        }
        System.out.println("\nEnd !!");
    }
}


//---------------------------------------------------------------------------//
// Ex0129_02.java : Runtime 예
public class Ex0129_02 {
    public static void main(String[] ar) {
        Runtime rt = Runtime.getRuntime();
        try {
            rt.exec("explorer.exe http://www.daum.net");
        } catch(java.io.IOException ee) { }
    }
}


//---------------------------------------------------------------------------//
// Ex0129_03.html

<html>

    <head>  
        <title> 시간보기 </title>
    </head>
    <body bgcolor=000000 text=ffffff>
        <center>
            <h2> 이것은 애플릿 </h2><p>
            <applet code="Ex0129_03.class" width=500 height=300>
            <!-- <param name="이름" value="값"> -->
            </applet>
        </center>
        <hr>
        <a href="Ex0129_03.java"> 소스보기 </a>
    </body>
</html>

// Ex0129_03.java

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Ex0129_03 extends Applet 
                implements RunnableActionListener{
    private Button bt = new Button("Yahoo!");
    private Button bt1 = new Button("Empas!");
    private Button bt2 = new Button("Naver!");
    private Runtime rt;
    public void init(){
        rt = Runtime.getRuntime();
        this.setLayout(new BorderLayout());
        Panel p = new Panel(new FlowLayout());
        p.add(bt);
        p.add(bt1);
        p.add(bt2);
        this.add("South", p);
    }
    public void start(){
        Thread tt = new Thread(this);
        tt.start();
        bt.addActionListener(this);
        bt1.addActionListener(this);
        bt2.addActionListener(this);
    }
    public void run(){
        while(true){
            try{
                Thread.sleep(1000);
            }catch(InterruptedException ee){}
            this.repaint();
        }
    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource() == bt){
            try{
                rt.exec("explorer.exe http://www.yahoo.co.kr");
            }catch(Exception ee){}
        }
        else if(e.getSource() == bt1){
            try{
                rt.exec("explorer.exe http://www.empas.com");
            }catch(Exception ee){}
        }
        else if(e.getSource() == bt2){
            try{
                rt.exec("explorer.exe http://www.naver.com");
            }catch(Exception ee){}
        }
    }
    public void paint(Graphics g){
        Calendar ca = Calendar.getInstance();
        String str = ca.get(Calendar.YEAR+ "년 " + 
                (ca.get(Calendar.MONTH+ 1+ "월 " +
                ca.get(Calendar.DAY_OF_MONTH+ "일 " +
                ca.get(Calendar.HOUR_OF_DAY+ "시 " + 
                ca.get(Calendar.MINUTE+ "분 " + 
                ca.get(Calendar.SECOND+ "초";
        g.setFont(new Font("TimesRoman"Font.BOLD20));
        g.drawString("Time : " + str, 50100);
    }
    public static void main(String[] ar){
        Ex0129_03 es = new Ex0129_03();
        es.init();
        es.start();
        Frame f = new Frame();
        f.setLayout(new BorderLayout());
        f.add("Center", es);
        f.setSize(500300);
        f.setVisible(true);
    }
}

//===========================================================================//