예를들면 메세지를 보낼때 동영상을 보내면서 메세지를 주고받는 경우 두개의 쓰레드가 활성화 되어있는 상태다.
📌 멀티쓰레드
대부분의 프로그램은 멀티쓰레드로 작성된다
시스템 자원을 보다 효율적으로 사용할수 있다.
사용자에 대한 응답성이 향상된다.
작업이 분리되어 코드가 간결해진다
하지만, 동기화에 주의해야하며 Dead-lock(교착상태)가 발생하지 않도록 주의해야한다.
프로그램 작성 당시 각 쓰레드가 효율적으로 고르게 실행될수 있도록 작성해야한다.
📌 쓰레드 구현
쓰레드를 구현하는 방법은 Thread 클래스를 상속 받거나, Runnable 인터페이스를 구현하는 방법으로 두가지가 있다.
Thread 클래스를 상속받게되면 다른 클래스를 상속받을수 없기 때문에 Runnable 인터페이스를 구현하는 것이 일반적이다.
class ThreadOne extends Thread {
@Override
public void run() { }
}
class ThreadTwo implements Runnable {
@Override
public void run() { }
}
쓰레드를 구현하는것은 run(){}메소드를 오버라이딩하여 구현하는것이다.
작성한 쓰레드 클래스는 만들어진 방법별로 인스턴스 생성 과정이 다르다.
public class ThreadStudy {
public static void main(String[] args) {
// Thread 클래스의 상속을 받은 클래스는 일반적인 인스턴스 생성을 하면된다.
ThreadOne t1 = new ThreadOne();
// 인터페이스를 구현한 경우 구현한 클래스를 Thread 클래스의 생성자 매개변수에 작성
Thread t2 = new Thread(new ThreadTwo());
t1.start(); // 쓰레드는 start 메소드로 실행한다
t2.start();
}
}
// ========== 작성한 쓰레드 클래스=========
class ThreadOne extends Thread {
@Override
public void run() {
for(int i=0; i<5; i++)
System.out.println(getName());
}
}
class ThreadTwo implements Runnable {
@Override
public void run() {
for(int i=0; i<5; i++){
System.out.println(Thread.currentThread().getName());
}
}
}
Thread 클래스를 상속받은 경우 Thread의 메소드 getName() 을 직접 호출 할수 있지만, Runnable 인터페이스를 구현한 경우 Thread의 메소드를 직접적으로 접근할수 없기 때문에 currentThread()메소드로 현재 쓰레드를 참조하여 접근할수 있다.
쓰레드는 내부 메소드 run을 호출하는 것이 아닌 start()메소드를 호출하여 실행한다.
쓰레드의 실행 순서는 OS 스케줄러가 결정하며, 코드 작성 순서대로 실행된다는 보장은 없다
Thread.getName으로 호출한 쓰레드 이름은 직접 지정하지 않으면 0부터 시작되어 자동 부여된다.