독립적인 프로세스 실행단위.
한 번에 두 가지 이상의 프로세스(운영체제에서 실행중인 하나의 프로그램)을 실행 가능하게 해준다.
실제로 동시에 두 개가 실행되는 것은 X.
운영체제 내부에서 CPU의 프로세스를 쪼개서 각각 Time Slot에 넣고 번갈아 실행하는 것이다.
동시에 돌아가는 것처럼 보이도록 아주 빠르게 번갈아서 스레드 실행이 되는 것인데 사람은 느끼지 못한다.
//Single Thread
class ThreadEx extends Thread { //내장되어 있는 Thread를 상속
@Override
public void run(){
for(int i=0; i<=10; i++)
{
System.out.println("Thread activation");
}
}
}
public class Test07 {
public static void main(String[] args) {
ThreadEx t = new ThreadEx();
t.run(); //t.start()를 사용하여 병령 쓰레드를 실행시킬 수 있다.
System.out.println("End of Main class");
}
}
쓰레스 실행 함수.run() 순서대로 나오는 함수start() 병렬처리되는 함수 - sleep() 는 try - catch 를 사용해야 한다.
class Thread_mul1 extends Thread{
@Override
public void run() {
for (int i=0; i<=50; i++) {
System.out.print("1");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thread_mul2 extends Thread{
@Override
public void run() {
for (int i=0; i<=50; i++) {
System.out.print("2");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class App {
public static void main(String[] args) {
// Thread_mul1 ts = new Thread_mul1();
// Thread_mul2 as = new Thread_mul2();
// ts.run();
// as.run();
Thread_mul1 mt1 = new Thread_mul1();
Thread_mul2 mt2 = new Thread_mul2();
mt1.start();
mt2.start();
}
}
class Thread_Ex extends Thread {
private int[] temp;
public Thread_Ex() { // 생성자
temp = new int[10];
// 이 클래스 밖에서 이를 이용한 생성자 생성은 Thread_Ex temp = new Thread_Ex(),
// temp.run/start() 이런 식으로 처리했어야 한다.
for (int i = 0; i < temp.length; i++) {
temp[i] = i;
}
}
public void run() {
for (int i : temp) {
// 확장 for문 : temp에 데이터가 있는 동안
try {
Thread.sleep(1000); // 1초 대기
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("temp: " + temp[i]);
}
}
}
public class Test02 {
public static void main(String[] args) {
Thread_Ex te1 = new Thread_Ex();
te1.run();
// 멀티 처리를 위한 start()를 호출하면 단일 처리를 해주는 run()도 실행된다.
try {
Thread.sleep(2000); // 2초
System.out.println("프로그램 종료");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Thread Class (java.lang.Thread;)에는 많은 메써드가 있는데, 그 중 단일 쓰레드는 run()를 사용하고,멀티 쓰레드는 start()를 오버라이드해서 사용할 수 있는데, start() 내부적으로 run()도 실행된다.
시차 주기object.sleep(sec); 주어서 두 쓰레드 사이에 격차를 주고, 실행시키기도 한다. - Thread class와 동일한 개념으로 사용될 수 있는 것으로 Runnable interface를 사용할 수 있다.
class Thread_Ex extends Thread {...} 를
class Runnable_Ex implements Runnable { ...} 식으로 변경해주면 된다.
이 Runnable Interface 에서는 단일 쓰레드만 빠르게 취급하므로 run() 하나만 사용하면 된다.
start()를 사용한다면, 객체를 생성해서 사용하면 된다.
class Runnable_Ex implements Runnable {...} Interface
Runnable interface는 재사용성이 높다. (일단, Thread class를 상속받으면 다른 클래스를 상속받기 어렵기에
여러 클래스를 쉽게 상속받을 수 있는 인터페이스가 좋을 수 있다.)
Runnable 코드의 일관성을 유지할 수 있어서 일부 수행에서는 Thread 보다 더 효율적일 수 있다.
run() 을 호출하는 것은 생성된 쓰레드를 실행하는 것이 아니라 클래스의 메서드를 실행하는 것이지만,
Start()를 사용하면 실행에 필요한 스택(stack:메모리)를 확보한 뒤, run()을 각각 호출해서 사용하기 때문에 멀티 쓰레드가 가능한 것 이다.
class Thread_ex2 implements Runnable {//class Thread_ex2 extends Thread
int temp[];
public Thread_ex2(){
temp = new int[10];
for (int i = 0; i < temp.length; i++) {
temp[i] = i;
}
}
public void run(){
for(int i =0; i<temp.length; i++){
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
System.out.println("temp: " + temp[i]);
}
}
}
public class Test03 {
public static void main(String[] args) {
Thread_ex2 te1 = new Thread_ex2();
Thread te2 = new Thread(te1); //Thead_ex2 te2 = new Thread_ex2();
te2.start();
}
}
public class Test04 implements Runnable {
@Override
public void run() {
System.out.println("run");
first();
}
public void first(){
System.out.println("first");
second();
}
public void second(){
System.out.println("second");
}
public static void main(String[] args) {
System.out.println("Starting main class");
Test04 tt1 = new Test04();
Thread tt2 = new Thread(tt1);
tt2.start();
// try {
// Thread.sleep(1);
// } catch (Exception e) {
// e.printStackTrace();
// }
System.out.println("Ending main class");
}
}
Starting main class
Ending main class
run
first
second
run()를 쓰면,
Starting main class
run
first
second
Ending main class
결과를 보면, ' 메인 클래스 시작 ' > run() > first() > second() > ' 메인 클래스 종료 '
순으로 나와야 할 것 같지만 실제로 그렇지 않다.
' 메인 클래스 시작 ' 한 뒤, start()를 호출하기에 run()로 실행되고, first(), second(), main class로 와서 ' 메인 클래스 끝 ' 을 보여야 하지만,
' 메인 클래스 시작 ' > ' 메인 클래스 종료 ' > run() > first() > second() 이렇게 출력이 된다.
메인 클래스가 실행된 이후에, Thread 객체를 호출하고, start()를 사용해 run()를 호출했지만 run()가 호출되기 전에 그 아래 줄인 ' 메인 클래스 종료 ' 가 먼저 출력되었기 때문이다.
- 이처럼 Thread 를 사용하면, ' 위에서 아래로, 좌에서 우 ' 로 라고 하는 작업순서를 따르게 되지 않을 수 있다.
JAVA Thread synchronized 쓰레드 동기화, wait() notify() (0) | 2022.08.03 |
---|---|
JAVA Thread (Daemon, join() ) (0) | 2022.08.03 |
JAVA JFrame / Exception 예외처리 / printStackTrace() (0) | 2022.08.01 |
JAVA 접근제어자 개념 정리, Static (0) | 2022.07.29 |
JAVA 내부 클래스 (0) | 2022.07.29 |