java에서 thread를 만드는 방법은 2가지가 있다.
package ch20;
class MyThread extends Thread {
//run은 thread가 실행되면 불리는 함수이다.
public void run() {
int i;
for (i=1;i<=200;i++) {
System.out.print(i + "\t");
}
}
}
public class ThreadTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread() + "start");
// Thread.currentThread()의 결과인 Thread[main,5,main]은
// 첫번째 main은 thread를 호출한 함수를 의미하며 (여기서는 main함수)
// 두번째 5는 priority, 세번째는 해당 thread가 속해있는 위치를 의미한다.
MyThread th1 = new MyThread();
MyThread th2 = new MyThread();
// thread class는 start()메소드 실행하면 thread가 실행된다.
th1.start();
th2.start();
System.out.println(Thread.currentThread() + "end");
}
}
package ch20;
class MyThread2 implements Runnable {
@Override
public void run() {
// TODO Auto-generated method stub
int i;
for (i=1;i<=200;i++) {
System.out.print(i + "\t");
}
}
}
public class ThreadTest2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread() + "start");
MyThread2 runnable = new MyThread2();
Thread th1 = new Thread(runnable);
Thread th2 = new Thread(runnable);
th1.start();
th2.start();
System.out.println(Thread.currentThread() + "end");
}
}
MyThread2 th1 = new MyThread2();
th1.start();
※ Thread를 상속한 class는 위와 같이 사용하였다면 Runnable을 구현한 class는 아래와 같이 사용해야한다.
MyThread2 runnable = new MyThread2();
Thread th1 = new Thread(runnable);
th1.start();
Runnable run = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("\nRun");
}
};
run.run();
Priority는 1부터 10까지 있으며 Defualt priority는 5이다.
우선순위가 높다고 무조건 CPU배분을 먼저 받는것은 아니고 배분 받을 확률이 높은 것이다.
단, Priority가 차이가 분명하게 나면 배분 순서도 확실히 정해진다.
setPriority()/getPriority()를 통해 priority를 주고 읽어올 수 있다.
Thread.MIN_PRIORITY(=1), Thread.MAX_PRIORITY(=10), Thread.NORMAL_PRIORITY(=5)를 통해 우선순위 세팅을 할 수도 있다.
class PriorityThread extends Thread{
public void run(){
int sum = 0;
Thread t = Thread.currentThread();
System.out.println( t + "start");
for(int i =0; i<=1000000; i++){
sum += i;
}
System.out.println( t.getPriority() + "end");
}
}
public class PriorityTest {
public static void main(String[] args) {
int i;
for(i=Thread.MIN_PRIORITY; i<= Thread.MAX_PRIORITY; i++){
PriorityThread pt = new PriorityThread();
pt.setPriority(i);
pt.start();
// Priority들의 차이가 별로 안커서 끝난 순서가 1부터 완전히 순서대로 실행되지는 않는다.
}
}
}
동시에 2개 이상의 Thread가 실행 될 때 하나의 Thread가 다른 Thread의 결과를 참조하여 실행해야 하는 경우 join()을 사용한다.
join()을 호출 한 Thread는 다른 Thread의 수행이 끝날때까지 non-runnable(waiting)상태로 가며 다른 Thread의 수행이 끝나면 다시 Runnable(Running)상태로 돌아가서 작업을 수행한다.
join을 하면 해당 thread의 작업이 끝날때까지 다른 Thread가 non-runnable상태로 작업이 끝나기를 기다려야한다. 작업이 끝나면 main을 꺠우기 위해 InterruptException을 통해 깨운다.
Interrupt는 요청한 작업이 끝났다는 것을 알리기 위해 보내는 신호이다.
Thread가 join(), sleep(), wait() 함수에의해 non-runnable 상태가 되었을 때 interrupt() 메서드를 호출하면 다시 runnable상태가 될 수 있다.
다른 Thread에 예외를 발생시키는 interrupt를 보내서 다시 작업이 실행되게 해준다.
package ch21;
public class JoinTest extends Thread{
int start;
int end;
int total;
public JoinTest(int start, int end) {
this.start = start;
this.end = end;
}
public void run() {
int i;
for (i = start; i < end; i++) {
total += i;
}
}
public static void main(String[] args) {
JoinTest jt1 = new JoinTest(1,50);
JoinTest jt2 = new JoinTest(51,100);
/* 이렇게 join을 하지 않는 경우 print를 하는 순간 결과가 다 안나온 상태라
* 실행을 할때마다 값이 달라지고 0이라는 결과가 나오기도 한다.
jt1.start();
jt2.start();
int lastTotal = jt1.total + jt2.total;
System.out.println("jt1.total = " + jt1.total);
System.out.println("jt2.total = " + jt2.total);
System.out.println("lastTotal = " + lastTotal);
*/
jt1.start();
jt2.start();
// join을 하면 해당 thread의 작업이 끝날때까지
// 다른 Thread(여기서는 main)이 non-runnable상태로 다음 작업을 기다려야한다.
// 작업이 끝나면 main을 꺠우기 위해 interruptException을 통해 깨운다.
try {
jt1.join();
jt2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int lastTotal = jt1.total + jt2.total;
System.out.println("jt1.total = " + jt1.total);
System.out.println("jt2.total = " + jt2.total);
System.out.println("lastTotal = " + lastTotal);
}
}
import java.io.IOException;
public class TerminateThread extends Thread{
private boolean flag = false;
int i;
public TerminateThread(String name){
super(name);
}
public void run(){
while(!flag){
try {
sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println( getName() + " end" );
}
public void setFlag(boolean flag){
this.flag = flag;
}
public static void main(String[] args) throws IOException {
TerminateThread threadA = new TerminateThread("A");
TerminateThread threadB = new TerminateThread("B");
TerminateThread threadC = new TerminateThread("C");
threadA.start();
threadB.start();
threadC.start();
int in;
while(true){
in = System.in.read();
if ( in == 'A'){
threadA.setFlag(true);
}else if(in == 'B'){
threadB.setFlag(true);
}else if( in == 'C'){
threadC.setFlag(true);
}else if( in == 'M'){
threadA.setFlag(true);
threadB.setFlag(true);
threadC.setFlag(true);
break;
}
}
System.out.println("main end");
}
}