**Thread
=>프로그래밍에서 가장 중요한 개념 중의 하나인데, 실제 생성해서 사용하는 경우는 안드로이드나 자바 애플리케이션을 만들 때이고
Web이나 Programming에서는 직접 생성해서 사용하는 경우가 드뭅니다.
1.작업 단위
1)Process : 실행 중인 프로그램
=>프로세서를 할당받아서 실행되는 것
=>한 번 실행되면 자신의 작업이 종료될 때 까지 제어권을 다른 프로세스에게 넘기지 않고 계속 수행됩니다.
2)Thread : Process를 작게 나누어서 작업을 수행하는 단위
=>Thread는 단독으로 실행될 수 없고 Process 안에서 실행되어야 합니다.
=>자신의 작업 도중 쉬는 시간이 생기거나 일정한 시간이 지나면 다른 스레드에게 제어권을 양도할 수 있습니다.
스레드가 동시에 처리한다고 오해하곤 하는데, 동시에 처리하는건 parallel이다.
밥과 빨래를 한다고 가정하자, 밥을 다 하고 빨래를 하면 Process고, 밥을 하면서 쉬는 시간(밥솥을 키고 가동하는 시간)동안 빨래를 하는 게 Thread. 동시에 하는 게 아니다.
2.Thread Programming을 할 때 반드시 알아야 될 사항
1)하나의 스레드가 사용 중인 자원은 다른 스레드가 수정하면 안된다.
=>Mutual Exclusion(상호 배제), Synchronus(동기화)
2)생산자와 소비자 문제
=>소비자는 생산자가 물건을 생성해 주어야만 작업을 수행
3)Dead Lock
=>결코 발생할 수 없는 사건을 무한정 기다리는 것
3.Java에서 Thread를 생성하는 기본적인 방법
1)Thread클래스로부터 상속받는 클래스를 만들고 Public void run이라는 메서드에 스레드로 수행할 내용을 작성한 후 인스턴스를 만들고 start메서드를 호출
2)Runnable 인터페이스로부터 상속받는 클래스를 만들고 public void run이라는 메서드에 스레드로 수행할 내용을 작성한 후
Thread 클래스의 인스턴스를 만들 때 생성자에 생성한 클래스의 인스턴스를 대입하고 Thread 클래스의 인스턴스가 start 메서드를 호출하면 됨
+α)3)Callable 인터페이스를 구현한 클래스를 이용해서도 생성 가능합니다.
4)메서드
Thread.sleep(long msec[,long nano]) ->[,]는 있을수도 있고 없을수도 있다는 뜻
=>msec밀리초동안 현재 스레드를 중지
nano를 입력하면 msec밀리초 + nano 나노초만큼 대기
+)windows에서는 nano초까지 갈만큼 처리가 안됨. windows에서는 nano초 안써도 됨
=>이 메서드를 사용할 때는 InterruptedException을 처리해주어야 합니다.
=>실습을 할 때 이 메서드를 사용하는 이유는 일정 시간 이상 대기를 해야만 다른 스레드에게 제어권이 이동되기 때문.
실제 시간의 의미는 거의 없음. Thread.sleep(long msec)의 msec자리에 1만 적어도 됨. 순차적으로 진행하는지 눈으로 확인하기 위해 1000을 적는 것. 정확하게 어떤 시간만큼을 주기 위할 때 아니면 의미 없음
5)Thread의 Priority(우선 순위)
=>여러 개의 스레드가 수행될 때 어떤 스레드가 먼저 되고 어떤 스레드가 나중에 수행될지는 알 수 없습니다.
=>우선순위를 설정하면 '확률적으로' 먼저 또는 자주 실행되도록 할 수 있습니다.
=>setPrioriy메서드를 이용해서 설정합니다.
setPrioriy(int priority)
-매개변수가 정수이지만 아무 정수나 사용하는 것은 안되고 제약이 있음
-일반 정수를 사용해도 에러는 발생하지 않지만 되도록이면 Thread.MAX_PRIORITY,NORMAL,MIN의 상수를 사용하는 것을 권장
Thread.MAX_PRIORITY로 하면 windows에서는 10, 리눅스에서는 7. 알아서 맞게 바꾸어 줌
6)실습
package java_1028.thread;
//Thread 클래스로부터 상속받는클래스를 생성
class ThreadEx extends Thread{
//public void run이라는 메서드 오버라이딩
@Override//안써도 에러는 나지 않음. 이 어노테이션은 상위 클래스나 인터페이스에서 제공하는 메서드가 아닌 경우 에러를 발생시켜 줌. 오버라이딩을 할 때 이름이 틀렸으면 에러가 남
public void run() {
//스레드로 수행할 내용
//1초마다 Thread 클래스라는 문장을 10번 출력
for(int i=0;i<10;i++) {
try {
Thread.sleep(1000);
System.out.println("Thread 클래스");
} catch (InterruptedException e) {
System.out.println(e.getLocalizedMessage());
}
}
}
}
//Runnable 인터페이스를 구현한 클래스를 생성
class RunnableImpl implements Runnable{
@Override
public void run() {
for(int i=0;i<10;i++) {
try {
Thread.sleep(1000);
System.out.println("Runnable 인터페이스");
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}
}
}
}
public class ThreadCreate {
public static void main(String[] args) {
//Thread클래스로부터 상속받은 클래스를 이용해서 스레드를 생성하고 실행
Thread th1 = new ThreadEx();
//start를 호출하면 run메서드의 내용을 수행
th1.start();//메서드 자체가 Thread의 run메서드를 호출하는 애임. run을 부르면 Process처럼 움직임.
//Runnable 인터페이스를 implements 하는 클래스를 이용해서 스레드를 생성하고 실횅
Thread th2 = new Thread(new RunnableImpl());//Runnable인터페이스는 별도로 실행하는 스레드를 호출해주는 역할
th2.start();
//Runnable 인터페이스를 Anonymous클래스를 이용해서 사용
Thread th3 = new Thread(new Runnable() {
public void run() {
for(int i=0;i<10;i++) {
try {
Thread.sleep(1000);
System.out.println("Anonymous 활용");
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}}}});
th3.start();
//Runnable 인터페이스는 public void run 메서드 1개만 소유
//즉, 람다 사용 가능
Thread th4 = new Thread(()->{for(int i=0;i<10;i++) {
try {
Thread.sleep(1000);
System.out.println("람다 활용");
} catch (Exception e) {
System.out.println(e.getLocalizedMessage());
}}});
th4.start();
}
}
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
Thread 클래스
Anonymous 활용
Runnable 인터페이스
람다 활용
+)관습
-일반적으로 개발자들은 클래스의 인스턴스를 1개만 생성할 때는 변수의 이름을 클래스 이름과 동일하게 만들고 첫글자만 소문자로 변경합니다
ex) String string = "asdfsadf";
-어떤 클래스로부터 상속받는 클래스를 1개만 만들 때는 클래스 이름 뒤에 Ex를 붙입니다
Thread 클래스로부터 상속받는 클래스
ex) class ThreadEx extends Thread{
}
-인터페이스를 구현한 클래스를 1개만 만들 때는 클래스 이름 뒤에 Impl을 붙입니다.
Runnable 인터페이스를 구현한 클래스
ex) class Runnablelmpi implements Runnable{
}
-extends하거나 implements했을 때 변수의 이름은 상위 클래스 이름이나 인터페이스 이름을 사용
ex) class ThreadEx extends Thread{
}
ThreadEx th = new ThreadEx();
Thread th = nes ThreadEx();
ex2)ArrayList<String> list = new ArrayList<>();
List<String> list = new ArrayList<>();
'JAVA' 카테고리의 다른 글
221031 Thread2. Multi Thread (0) | 2022.10.31 |
---|---|
221028 Daemon Thread (0) | 2022.10.28 |
221028 Stream API (0) | 2022.10.28 |
221028 Lambda (0) | 2022.10.28 |
221028 Anonymous Class (0) | 2022.10.28 |