멀티 태스킹

[Java] 멀티 태스킹의 스레드, 프로세스, 동기화
Jan 03, 2024
멀티 태스킹
멀티 태스킹은 여러 개의 작업을 동시에 실행하는 기법이다.

멀티 스레딩(multi-threading)

병렬작업의 아이디어를 하나의 애플리케이션 안으로 가져온 것이다.
각각의 작업을 스레드(thread)라고 한다.

사용이유

여러가지 작업을 동시에 진행할 때 속도를 빠르게 하기 위해 사용

프로세스와 스레드

  • 컴퓨터에는 프로세스(process)와 스레드(thread)라는 2가지의 실행 단위가 있다.
  • 프로세스 : 하드디스크에 있는 프로그램이 램으로 로드되는 것.
  • 모든 프로세스는 반드시 스레드를 하나 이상 가진다.

스레드 예제

public class ThreadEx01 { public static void sub1() { for (int i = 1; i <= 5; i++) { try { System.out.println("start1 thread : " + i); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } public static void sub2() { for (int i = 1; i <= 5; i++) { try { System.out.println("start2 thread : " + i); Thread.sleep(1000); } catch (InterruptedException e) { throw new RuntimeException(e); } } } // main thread public static void main(String[] args) { Thread t1 = new Thread(() -> { sub1(); }); t1.start(); // 실을 만드는 것 Thread t2 = new Thread(() -> { sub2(); }); t2.start(); // 실을 시작하는것 } // main 스레드 종료 }
t1.start()와 t2.start()는 순차적으로 실행 되는 것이 아니라 동시에 같이 실행된다.
람다식을 이용해서 스레드를 작성하는것이 간편하다.
 
class MyFile { // 하드디스크 기록 (I/O) public void write() { try { Thread.sleep(5000); // sleep은 예외처리가 필요함 System.out.println("파일 쓰기 완료"); } catch (InterruptedException e) { throw new RuntimeException(e); } } } class 화가 { public void 그림그리기() { System.out.println("그림 그리기 완료"); } } public class ThreadEx02 { public static void main(String[] args) { new Thread(() -> { MyFile mf = new MyFile(); mf.write(); }).start(); 화가 h = new 화가(); h.그림그리기(); } }

데드락

데드락(교착 상태)는 멀티 스레딩에서 얼마든지 나타날 수 있다. 교착 상태는 첫 번째 스레드가 두 번째 스레드가 획득한 객체 락을 기다리고 있고, 두 번째 스레드는 첫 번째 스레드가 획득한 객체 락을 기다리는 상황에서 발생할 수 있다. 두 스레드가 서로 상대방이 가진 락을 기다리고 있기 때문에, 아무리 시간이 경과하여도 교착 상태가 해결될 수 없다.
프로그램을 재시작 하는 방법 말고는 교착 상태를 해결하는 방법은 없다.
교착 상태가 일어나지 않도록 하는 것이 제일 중요하다.(동기화 사용)

동기화

  • 스레드가 동일한 메모리를 사용하기 때문에 일어나는 2가지 문제스레드 간섭(thread interference), 메모리 불일치 오류(memory consistency error)이다.
  • 위의 스레드 예제의 경우처럼 t1.start()와 t2.start()가 같이 실행되는 것.
  • 오류를 막는 도구를 동기화(synchronization)라고 한다.
 
임계 영역(critical section) : 동시에 사용하면 안 되는 자원을 하나의 스레드가 사용(락 설정)시작 부터 끝날 때(락 해제)까지 한번에 하나의 스레드만 실행 가능
 
동기화 사용 방법 : 공유 데이터를 조작하는 메소드 앞에 synchronized를 붙인다.
class Printer{ synchronized void print(int[] arr){ // synchronized 입력 for (int i = 0; i < arr.length; i++) { System.out.print(arr[i]+" "); try{ Thread.sleep(100); }catch(Exception e){ e.printStackTrace(); } } } } class MyThread1 extends Thread{ Printer prn; int[] myarr = {10, 20, 30, 40, 50}; MyThread1(Printer prn) { this.prn = prn; } public void run(){ prn.print(myarr); } } class MyThread2 extends Thread{ Printer prn; int[] myarr = {1,2,3,4,5}; public MyThread2(Printer prn) { this.prn = prn; } public void run(){ prn.print(myarr); } } public class TestSynchro { public static void main(String[] args) { Printer obj = new Printer(); MyThread1 t1 = new MyThread1(obj); MyThread2 t2 = new MyThread2(obj); t1.start(); t2.start(); } }
Share article
RSSPowered by inblog