스레드
프로세스 내에서 실제로 작업을 수행하는 주체
-> 일련의 코드의 실행 흐름
모든 프로세스에는 최소 1개 이상의 스레드가 존재하여 작업을 수행하며 두개 이상의 스레드를 가지는 프로세스를 멀티스레드 프로세스라 부른다

<프로그램 프로세스 스레드의 관계>
스레드를 이해해보자
package thread;
public class threadExam {
public static void main(String[] args) {
//하나의 스레드로 0부터 10억까지의 짝수를 더하는 프로그램
long startTime = System.currentTimeMillis();
long sum=0;
for(long i=0; i<=2000000000; i++) {
if(i%2==0) {
sum+=1;
}
}
System.out.println(sum);
long endTime = System.currentTimeMillis();
System.out.println("걸린시간 : " + (endTime - startTime) + "m/s");
}
}
결과값:
1000000001
걸린시간 : 1743m/s
스레드의 생성과 실행
스레드의 생성자는 Runnable 인터페이스를 구현한 객체만 전달가능
스레드는 에러가 많이 나기 때문에 try~catch (예외처리) 해야한다.
start메소드가 호출이 되면 Runnable의 run 메소드를 실행
-> 오버라이딩된 메소드가 있다면 오버라이딩된 run메소드를 실행
package thread;
public class threadExam implements Runnable{
public long sum = 0;
private final long from;
private final long to;
public threadExam(long from, long to) {
this.from = from;
this.to = to;
}
public static void useThread() {
try {
long startTime = System.currentTimeMillis();
long sum =0;
// 메인스레드가 A스레드, B스레드에게 작업 실행 명령
// A는 0~10억, B는 10억1~20억까지
// 최종적으로 두 스레드의 작업이 끝나면 결과를 가져와 합치면 짝수의 합을 뽑을 수 있다.
threadExam th1 = new threadExam(0,1000000000); //
Thread threadA = new Thread(th1);
threadExam th2 = new threadExam(1000000001,2000000000);
Thread threadB = new Thread(th2);
threadA.start();
threadB.start();
threadA.join(); // 호출하는 스레드를 기다리는 메소드. A 끝나면 B 실행
threadB.join(); //
System.out.println(th1.sum + th2.sum);
long endTime = System.currentTimeMillis();
System.out.println("걸린시간 : " + (endTime - startTime) + "m/s");
} catch (InterruptedException e) {
// TODO: handle exception
}
}
public static void notUseThread() {
long startTime = System.currentTimeMillis();
long sum =0;
for(long i = 0; i<=2000000000; i++) {
if(i%2==0) {
sum+=i;
}
}
System.out.println(sum);
long endTime = System.currentTimeMillis();
System.out.println("걸린 시간 : " + (endTime- startTime));
}
@Override
public void run() {
for(long i=0; i<=1000000000; i++) {
if(i%2==0) {
sum+=1;
}
}
}
public static void main(String[] args) {
//하나의 스레드로 0부터 10억까지의 짝수를 더하는 프로그램
notUseThread();
// useThread();
}
}
싱글 스레드와 멀티스레드 차이
<싱글스레드>
package thread;
import java.awt.Toolkit;
public class BeepPrint {
public static void main(String[] args) {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for(int i=0; i<5; i++) {
System.out.println("스레드명" + Thread.currentThread().getName());
toolkit.beep();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//for문 end
for(int i=0; i<5; i++) {
System.out.println("스레드명" + Thread.currentThread().getName());
System.out.println("띠요옹");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
<멀티스레드>
package thread;
public class BeepMultiMain {
public static void main(String[] args) {
// 멀티스레드 구현방법
Runnable runnable = new Beep();
Thread thread = new Thread(runnable);
for(int i=0; i<5; i++) {
System.out.println("스레드명" + Thread.currentThread().getName());
System.out.println("띠요옹");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
package thread;
import java.awt.Toolkit;
public class Beep implements Runnable{
@Override
public void run() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
for(int i=0; i<5; i++) {
System.out.println("스레드명" + Thread.currentThread().getName());
toolkit.beep();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//for문 end
}
}
//결과 :
스레드명main
띠요옹
스레드명main
띠요옹
스레드명main
띠요옹
스레드명main
띠요옹
스레드명main
띠요옹
// 메인에서 먼저 스레드명main+띠요옹 출력 후 비프음 발생.
// 동시에 실행되니 멀티스레드를 쓰면 10초 걸리던 것이 5초로 단축 됨.
자바 프로그램이 실행될 때 Main메소드를 거치면서 시작한다. 그 때 실행되는 스레드(무조건 싱행)
메인 스레드가 스레드(작업 스레드)를 만들어 코드를 병렬로 실행
몇 개의 작업을 병렬로 실행할지 설계단에서 결정할 필요가 있음
데몬스레드(DeamonThread)
메인스레드가 종료되면 서브스레드(멀티,작업스레드)의 작업이 끝나지 않았더라도 같이 종료되는 스레드
package thread;
public class FastRun implements Runnable{
public String name;
public FastRun(String name) {
this.name = name;
}
@Override
public void run() {
int sum=0;
for(int i=0; i<10000; i++) {
sum+=i;
}
System.out.println(name + ":" + sum);
}
}
package thread;
public class DaemonThreadExam {
public static void main(String[] args) {
Thread threadA = new Thread(new FastRun("김규동"));
threadA.setDaemon(true); // 해당 스레드를 데몬 스레드로 변경
Thread threadB = new Thread(new FastRun("조원재"));
threadB.setDaemon(true);
threadA.start();
threadB.start();
System.out.println("팀장님 퇴근함 오예!");
}
} //결과 : 메인 스레드 작업 종료시, 김규동, 조원재도 같이 작업 종료됨.