하나의 새로운 프로세스를 생성하는것보다 하나의 새로운 쓰레드를 생성하는것이 적은 비용이든다.
장점 : 시스템 자원을 보다 효율적으로 사용할수있다.
사용자에 대한, 응답성이 향상, 작업이 분리되어 코드가 간결해진다
단점 : 동기화에 주의,
교착상태가 발생하지 않도록 주의, 필요한것을 갖기 위해 대치하는 상황
각 쓰레드가 효율적으로 고르게 실행할수 있게 해야한다, 프로그래밍할때 고려해야할 사항이 많다.
Thread 클래스를 상속
class MyThread extends Thread{ //자바는 단일 상혹 public void run() { // Thread클래스의 run()을 오버라이딩 /*작업내용*/ } MyThread t1 = new MyThread(); //쓰레드의 생성 t1.start(); //쓰레드의 실행
Runnable 인터페이스를 구현(더 낫다)
class MyThread2 implements Runnable { //인터페이스를 구현하면 다른 클래스 클래스를 상속 받을수 있다 public void run() { // Rnnable 인터페이스의 run()을 구현 /*작업내용*/ } Runnable r = new MyThread2(); Thread t2= new Thread(r); // Thread(Runnable r) // run(){}이라는 메서드의 구현체를 외부에서 매개변수로 받는다. !!중요 //Thread t2 = new Thread(new MyThread2(); //위에 두줄을 한줄로 t2.start();
class Ex13_1 { public static void main(String args[]) { ThreadEx1_1 t1 = new ThreadEx1_1(); // Thread 의 자손 클래스의 인스턴스를 생성 Runnable r = new ThreadEx1_2(); //Runnable 을 구현한 클래스의 인스턴스를 생성 Thread t2 = new Thread(r); // 생성자 Thread(Runnable target) // 생성자매개변수로제공해야함 t1.start(); t2.start(); //// start 했다고 t1이 먼저 실행이 되는건 아니다 start하면 실행 가능한 상태가 되는거지 바로 실행 되는게 아니라 //os스케쥴러가 실행순서를 결정 } } class ThreadEx1_1 extends Thread { // 1.Thread 클래스를 상속해서 쓰레드를 구현 (run을 완성 public void run() { //쓰레드가 수행할 작업 for(int i=0; i < 5; i++) { System.out.println(this.getName()); // 조상인 Thread의 getName()을 호출 } } } class ThreadEx1_2 implements Runnable { // 2.Runnable인터페이스를 구현해서 쓰레드를 구현 (run을 완성 public void run() {//쓰레드가 수행할 작업 for(int i=0; i < 5; i++) { // Thread.currentThread() - 현재 실행중인 Thread를 반환한다. System.out.println(Thread.currentThread().getName()); // 쓰레드 상속을 받질 않고 Runn~ 구현 받은경우엔 Thread.currentThread()메서드를 이용해서 객체에접근 } } } 000000000000001111111111111111000000000000000000011111111100000000111000 01이번갈아 가며 출력된다
class Ex13_1 { public static void main(String args[]) { ThreadEx1_1 t1 = new ThreadEx1_1(); Runnable r = new ThreadEx1_2(); Thread t2 = new Thread(r); // 생성자 Thread(Runnable target) t1.start(); t2.start(); for(int i=0; i < 5; i++) { System.out.println(this.getName()); // 조상인 Thread의 getName()을 호출 } for(int i=0; i < 5; i++) { // Thread.currentThread() - 현재 실행중인 Thread를 반환한다. System.out.println(Thread.currentThread().getName()); // 쓰레드 상속을 받질 않고 Runn~ 구현 받은경우엔 Thread.currentThread()메서드를 이용해서 객체에접근 } } } 00000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000 11111111111111111111111111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111111111111111111111111
쓰레드의 실행 start()
쓰레드를 생성한 후에 start(0를 호출해야 쓰레드가 작업 시작한다.
ThreadEx1_1 t1 = new ThreadEx1_1(); //t1 쓰레드 생성
ThreadEx1_1 t2 = new ThreadEx1_1(); //t2 쓰레드 생성
t1.start(); // 쓰레드t1.을 실행한다.
t2.start(); //
// start 했다고 t1이 먼저 실행이 되는건 아니다 start하면 실행 가능한 상태가 되는거지 바로 실행 되는게 아니라
//os스케쥴러가 실행순서를 결정 어떤 쓰레드가 얼마의 쓰레드가 돌아갈지 결정 되기 때문에 실행될 시간과 순서를 정할수 없다
main 쓰레드
main 메서드에서 코드를 수행하는 쓰레드
사용자 쓰레드 (메인쓰레드)
데몬 쓰레드 = 사용자 쓰레드가 하는 작업을 보조해주는 역할 보조쓰레드
실행중인 사용자 쓰레드가 하나도 없을떄 프로그램을 종료된다.
메인메서드가 종료되도 다른 쓰레드가 실행중이면 프로그램이 종료되지 않는다.
join 메서드 : 다른 쓰레드 작업 끝날떄까지 기다린다.
싱글쓰레드때 멀티 쓰레드가 시간이 더 걸린다. 실행할 작업에대한 정보가 바뀌기떄문에 시간이 소요가 더걸린다.
but 시간이더 걸리더라도 두가지 작업을 동시에 할수 있다.
Contextswitching A작업 ->B작업
input/output /입출력
blocking 입출력시 일시적인 작업중단 자원을 효율적으로 사용하기 위해