-
Java - ThreadJava 2018. 1. 30. 14:57반응형// Thread는 어떤 program을 실행 하게 해주는 원동력이다// 대표적으로 main(String[] args)로 실행 한다.// process는 1개 이상의 thread로 구성되어 있다.// process는 thread로 구성 된다.// 메모리 공유 부분에서 process는 메모리 공유가 안되지만,// Thread는 메모리 공유가 된다.// main method는 main thread를 생성 한다.// 처리가 버거우면 work thread를 생성할 수 있다.// 이것을 multi thread라 한다.// Runnable Interface, Thread Class 상속으로 생성할 수 있다.< Runnable >public class Main {public static void main(String[] args) {// 워크 스레드 생성 - Runnable 객체를 구현 받는 방법Runnable job = new Job(); // 1.쓰레드가 해야할 일 생성Thread work = new Thread(job); // 2. 그 일을 해야할 스레드 생성work.start(); // 3. 해당 스레드 시작/*메인 Thread가 하는 일*/for(int i = 1 ; i <= 5; i++) {System.out.println("i의 값은 : "+i);try {Thread.sleep(500); // 0.5초간 차} catch (InterruptedException e) {e.printStackTrace();}}// 워크 스레드가 메인 스레드 아래있으면 메인스레드부터 실행되고 워크 스레드가 실행된다.// 워크 스레드가 위에 있으면 메인스레드와 같이 일한다.}}public class Job implements Runnable {@Overridepublic void run() { // Thread 실행시 해야만 하는 일for(int i = 1 ; i <= 5; i++) {System.out.println("work thread -> i의 값은 : "+i);try {Thread.sleep(500); // 0.5초간 차} catch (InterruptedException e) {e.printStackTrace();}}}}< AnonyMous Runnable >public class AnonyMain {public static void main(String[] args) throws InterruptedException {// 워크 스레드 생성Thread th = new Thread(new Runnable() { // 익명 객체로 따로 만들어버린다.@Overridepublic void run() {for(int i = 1 ; i <= 5; i++) {System.out.println("work thread -> i의 값은 : "+i);try {Thread.sleep(500); // 익명 객체는 한번쓰고 말것이기때문에 누군가 한테 throws를 할 수 없다.} catch (InterruptedException e) {e.printStackTrace();}}}});th.start();// 메인스레드 수행for(int i = 1 ; i <= 5; i++) {System.out.println("i의 값은 : "+i);Thread.sleep(500); // 0.5초간 차}}}< Thread >public class Job extends Thread {@Overridepublic void run() { // Thread 실행시 해야만 하는 일for(int i = 1 ; i <= 5; i++) {System.out.println("work thread -> i의 값은 : "+i);try {Thread.sleep(500); // 0.5초간 차} catch (InterruptedException e) {e.printStackTrace();}}}}public class Main {public static void main(String[] args) {// 워크 스레드 생성 - Runnable 객체를 구현 받는 방법Thread job = new Job(); // 1.쓰레드가 해야할 일 생성job.start(); // 2. 해당 스레드 시작/*메인 Thread가 하는 일*/for(int i = 1 ; i <= 5; i++) {System.out.println("i의 값은 : "+i);try {Thread.sleep(500); // 0.5초간 차} catch (InterruptedException e) {e.printStackTrace();}}}}< Name >public class WorkThread extends Thread {@Overridepublic void run() {for(int i=1;i<=5;i++) {System.out.println(getName() + " 스레드가 출력한 내용 : "+i);// Thread 자체이기때문에 getName()사용// 스레드 이름 얻어오기try {Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}}}public class MainThread {public static void main(String[] args) {Thread th = new WorkThread();th.setName("First"); // Thread Name 지정th.start();th = new WorkThread();th.setName("Second");th.start();th = new WorkThread();th.setName("Third");th.start();}}Runnable Interface 구현 1. 쓰레드가 해야할 일 생성 - Runnable 객체 생성 2. 그 일을 해야할 스레드 생성 - Thread 생성 3. 해당 스레드 시작 Thread Class 상속 1. 쓰레드가 해야할 일 생성 - 바로 Thread 생성 2. 해당 스레드 시작 둘 다 익명객체 사용 가능-> 메모리 관리 가능, 한번만 사용할 때, 객체생성 필요없음< Thread Priority >// Thread에 순서가 없어서 제어가 어렵다.// Thread는 Round robin방식을 사용하기 때문이다.// 빨리 일을 끝내면 다음 일을 받는 방식이므로 먼저 시작했다고 먼저 끝나지 않는다.Thread Priority -// 시작과 동시에 우선순위를 부여하므로 짧은 작업에는 의미가 없다.// 우선순위는 1~10까지 줄 수 있다.// 우선순위가 같을 경우는 빠른놈이 먼저다.// 상수로 값을 대신할 수 있다.// 상수 - > Thread.MIN_PRIORITY -> 1// Thread.MAX_PRIORITY -> 1// Thread.NORM_PRIORITY -> 5// 우선순위를 줄 수 있지만, 허술한점이 많아서 잘 사용되지 않는다.public class WorkThread extends Thread {public WorkThread(String name) {setName(name); // 스레드 이름 생성}@Overridepublic void run() {System.out.println(getName()+" 스레드 시작");for(int i=0;i<=100000;i++) {// 이 시간동안 작업한다고 가정}System.out.println(getName()+" 스레드 시작");}}public class Main {public static void main(String[] args) throws InterruptedException {// 우선순위는 1~10까지 줄 수 있다.// 우선순위가 같을 경우는 빠른놈이 먼저다.// 상수로 값을 대신할 수 있다.// 상수 - > Thread.MIN_PRIORITY -> 1// Thread.MAX_PRIORITY -> 10// Thread.NORM_PRIORITY -> 5for(int i=1; i<=5; i++) {Thread th = new WorkThread(i+"번 스레드");th.setPriority(i); // 우선순위 지정th.start();Thread.sleep(1000) // sleep으로 어느정도 구분 지을 수 있다.}// 우선순위로는 제어가 정확히 어렵다.// 그래서 정확한 제어를 위해서는 다른 메서드를 제공해 준다.}}
< Synchronized >
// Thread는 객체 간의 데이터의 간섭이 일어 나기도 한다.// Synchronized는 다른 데이터의 간섭을 막을 수 있다.// vector와 비슷// Syncronized 방법은 크게 2가지다// Syncronized method를 사용 하는 방법과// Syncronized block을 사용 하는 방법이 있다.public class Computer {private int score;// 컴퓨터를 아무나 쓸 수 있어서 데이터가 뒤섞인다./*public void setScore(int score) {this.score = score;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" : "+this.score);// 현재 활성화 되있는 스레드의 이름과 점수}*/// 컴퓨터에 Lock를 건다.// Synchronized 메서드는 한번에 하나의 스레드만 접근 한다.public synchronized void setScore(int score) {this.score = score;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" : "+this.score);// 현재 활성화 되있는 스레드의 이름과 점수}// 특정 영역만 접근을 제한한다.public void setScore(int score) {// 이 블럭 부분만 제한해서 실행한다.synchronized (this) { // this == Computerthis.score = score;try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+" : "+this.score);}}}public class User1 extends Thread {private Computer com;public User1(Computer com) {this.com = com;setName("user1");}@Overridepublic void run() {com.setScore(500);}}public class User2 extends Thread {private Computer com;public User2(Computer com) {this.com = com;setName("user2");}@Overridepublic void run() {com.setScore(100);}}public class PcRoom {public static void main(String[] args) {Computer com = new Computer();User1 user1 = new User1(com);User2 user2 = new User2(com);user1.start();user2.start();}}< Thread State >// Thread는 생성부터 종료까지의 값이 된다.// getState()를 통해 현재 상태를 알 수 있다.// new -> runnable -> 실행 -> terminatedpublic class WorkThread extends Thread {@Overridepublic void run() {// 실행for(long i=0; i<=10000000; i++) {}// 1.5초 휴식try {Thread.sleep(1500);} catch (InterruptedException e) {e.printStackTrace();}// 실행for(long i=0; i<=10000000; i++) {}}}import java.lang.Thread.State;public class Main {private static Thread.State state;public static void main(String[] args) {// 워크 스레드 생성 -> 실행 -> 일시정지 -> 실행 -> 종료// 메인스레드에서 정지Thread th = new WorkThread();while(true) {state = th.getState();System.out.println("work thread state : "+state);if(state == Thread.State.NEW) {th.start();}// terminated가 되었을때 감시를 멈추고 싶다면?if(state == Thread.State.TERMINATED) {break;}// 0.1초 간격으로 감시하고 싶다면?try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}< Thread Control >// sleep()은 ms동안 thread를 일시 정지 시킨다. - 제한시간이있다.// yield()는 특정 스레드에게 제어권을 양보한다. - 제한시간이없다// yield는 다른 thread에게 일을 처리할 길을 터주면서 자신의 일도 수행한다.// 자기 자신이 쉬는 의미가 아니라, 다른 스레드도 실행할 수 있는 기회를 양보 하는 것이다.public class ThreadA extends Thread {boolean stop = false;boolean yield = false;@Overridepublic void run() {while(!stop) {if(yield) {System.out.println("Thread B 에게 양보");Thread.yield();}System.out.println("Thread A 동작중");try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Thread A 중지");}}public class ThreadB extends Thread {boolean stop = false;boolean yield = false;@Overridepublic void run() {while(!stop) {if(yield) {System.out.println("Thread A 에게 양보");Thread.yield();}System.out.println("Thread B 동작중");try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("Thread B 중지");}}public class Main {public static void main(String[] args) throws InterruptedException {ThreadA thA = new ThreadA();ThreadB thB = new ThreadB();thA.start();thB.start();thA.yield = true; // A에게 양보하라고 함 -> B동작Thread.sleep(500);thA.yield = false;thB.yield = true;Thread.sleep(500);thA.stop = true;thB.stop = true;}}< Join >// join은 다른 스레드의 종료를 기다린 후에 실행할 때 사용 한다.// 효용성 중요public class OperThread extends Thread {private int sum;public int getSum() {return sum;}@Overridepublic void run() {for(int i = 1; i <=100; i++) {sum += i;}}}public class Main {public static void main(String[] args) throws InterruptedException {OperThread th = new OperThread();System.out.println("1~100까지의 합은?");th.start();th.join(); // 일을 시키면 끝날 때 까지 기다려 준다.System.out.println("답 : "+th.getSum());}}< wait, notify, notifyAll >// wait() : 지정한 스레드를 일시 정지 상태로 만든다.// notify() : 일시 정지 상태중인 스레드 중 하나를 실행 대기 상태로 바꾼다.// notifyAll() : 일시 정지된 모든 스레드를 실행 대기 상태로 만든다.public class WorkObj {// 한번에 하나의 스레드만 접근 하도록// 하나의 스레드가 실행되는 동안 다른 스레드는 일시정지// 메서드를 사용하면 해당 스레드는 대기하고 다른 스레드를 깨운다.// synchronized는 동시접근 불가public synchronized void work() { // synchronized로 하나만 들어오게 한다System.out.println(Thread.currentThread().getName()+" 실행 중");notify(); // 다른 스레드를 깨워준다.try {wait(); // 스스로 대기} catch (InterruptedException e) {e.printStackTrace();}}}public class WorkThread extends Thread {private WorkObj obj;public WorkThread(WorkObj obj) {this.obj = obj;}@Overridepublic void run() {for(int i=1; i<5; i++) {obj.work();}}}public class Main {public static void main(String[] args) {WorkObj obj = new WorkObj();WorkThread thA = new WorkThread(obj);WorkThread thB = new WorkThread(obj);thA.start();thB.start();}}반응형'Java' 카테고리의 다른 글
Java - Stop, Interrupt (0) 2018.01.31 Java - Wait, Notify (0) 2018.01.31 Java - 정규표현식 (0) 2018.01.26 Java - Stack, Queue (0) 2018.01.25 Java - Map (0) 2018.01.25 댓글