1. 쓰레드를 상속받아서 사용
    1. java.lang.Thread클래스 상속받기
    2. Thread의 run() 메소드 오버라이딩 (수행 흐름의 생겼을 때의 메인 메소드)
    3. start() 메소드를 호출 (흐름 생성)
public class MyThread1 extends Thread {
        String str;
        public MyThread1(String str){
            this.str = str;
        }

        public void run(){
            for(int i = 0; i < 10; i ++){
                System.out.print(str);
                try {
										Thread.sleep((int)(Math.random() * 1000));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  1. Runnable 인터페이스 이용하여 생성

    1. Runable 인터페이스의 run() 메소드 구현
    public class MyThread2 implements Runnable {
            String str;
            public MyThread2(String str){
                this.str = str;
            }
    
            public void run(){
                for(int i = 0; i < 10; i ++){
                    System.out.print(str);
                    try {
                        Thread.sleep((int)(Math.random() * 1000));
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    

    b. 인터페이스를 구현한 자료형 변수를 생성

    c. Thread를 생성한 다음 생성자에 변수를 넣음

    d. start() 메소드를 호출 (흐름 생성)

    public class ThreadExam2 {  
            public static void main(String[] args) {
                MyThread2 r1 = new MyThread2("*");
                MyThread2 r2 = new MyThread2("-");
    
                Thread t1 = new Thread(r1);
                Thread t2 = new Thread(r2);
    
                t1.start();
                t2.start();
                System.out.print("!!!!!");  
            }   
        }
    

    장점 : 다중 상속기능 이용