본문 바로가기
Java

Java_스레드와 동기화

by 유서담 2023. 12. 4.

프로세스와 스레드

 

 

프로세스

  • 하나의 프로그램이 실행될 때 운영체제로부터 실행에 필요한 자원을 독립적으로 할당받고 애플리케이션 실행에 필요한 환경을 제공한다.
  • 실행중인 프로그램 하나당 프로세스가 하나씩 생긴다.
  • 멀티태스킹(Multi tasking)
    • 동시에 두개 이상의 프로세스(프로그램)의 실행을 지원하는 것
    • 프로세스마다 실행에 필요한 자원(CPU, 메모리)들을 적절히 할당하고, 관리하는 기술이 필요하다

 

스레드

  • 프로세스가 수행문을 실행하기 위해서 사용하는 실행흐름(일꾼)이다.
  • 모든 프로세스는 하나 이상의 스레드를 가지고 있다.

 

 

프로그램을 스레드를 기준으로 구분

  • 싱글 스레드 프로그램 : 실행흐름이 하나뿐인 프로그램
  • 멀티 스레드 프로그램 : 실행흐름이 두개 이상인 프로그램

 

메인 스레드 : 모든 자바 프로그램은 main( ) 메소드의 수행문을 실행시키는 메인 스레드(Main Thread)를 가지고 있다

 

 

사용자정의 스레드 만들기

 

java.lang.Thread 클래스를 상속받아서 만들기

  public class MyThread extends Thread {
    public void run() {
      // 스레드로 수행시킬 작업
    }
  }
  
  // 스레드 생성 및 실행
  MyThread t = new MyThread();
  t.start();

 

 

Thread 클래스로 작성한 스레드 예시코드

 

 

 

java.lang.Runnable 인터페이스를 구현받아서 만들기 

  public class MyRunnable implements Runnable {
    public void run() {
      // 스레드로 수행시킬 작업
    }
  }

  // 스레드 생성 및 실행
  MyRunnable r = new MyRunnable();
  Thread t = new Thread(r);
  t.start();

 

 

Runnable 인터페이스로 구현한 스레드 예시코드

 

 

 

 


 

 

 

synchronize

 

동기화처리

  • 멀티스레드 환경에서 실행되는 프로그램이 임계값(여러 스레드가 동시에 변경할 수 있는 값)을 가지고 있다면, 해당 프로그램은 Thread - Unsafe한 프로그램이 된다
  • 멀티스레드의 동시접근을 차단하는 것이 동기화처리

 

동기화 블록 정의하기

  • 동기화처리된 메소드를 만든다
    • 메소드내의 모든 수행문이 동기화처리의 대상이 된다
  public class Sample {
    필드타입 필드명; //임계값

    public synchronized void work() {
      임계값을 변경하는 수행문;
      임계값을 변경하는 수행문;
      임계값을 변경하는 수행문;
      임계값을 변경하는 수행문;
      임계값을 변경하는 수행문;
    }
  }

 

  • 동기화 블록을 정의한다
  public class Sample {
    필드타입 필드명; // 임계값

    public void work() {
      그냥 수행문;
      그냥 수행문;
      synchronized(this) {
        임계값을 변경하는 수행문;
        임계값을 변경하는 수행문;
      }
      그냥 수행문;
    }
  }

 

 

 

콜렉션의 동기화처리

  • 동기화 처리가 지원되는 클래스를 사용
    • Vector (ArrayList 대신)
    • HashTable (HashMap 대신)
  • 동기화처리가 지원되지 않는 클래스를 동기화처리가 가능하게 하기
    • List list = Collections.synchronizedList(new ArrayList());
    • Set set = Collections. synchronizedSet(new HashSet());
    • Map<String, Object> map = Collections. synchronizedMap(new HashMap<String, Object>());

 

멀티스레드 환경에서 안전한 클래스 작성하기

  • 여러 스레드가 동시에 변경할 수 있는 필드를 정의하지 않는다
  • 필드를 읽기전용의 용도로 사용한다
  • 업무로직 수행에 필요한 값들은 해당 메소드내의 변수에만 저장한다

 

 

 

 

스레드 예시 코드

 

package thread3;

import java.util.Vector;

import javax.xml.stream.events.Namespace;



public class HorseRunnable implements Runnable {

	// 순위별로 경주마의 이름을 저장하는 객체
	private Vector<String> names = new Vector<String>();
	
	public Vector<String> getnames() {
		return names;
	}
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		String name = Thread.currentThread().getName();
		
		for(int i =1; i<=100; i++) {
			System.out.println("["+ name + "]이" + i + "미터 전진함");
			
			try {
				Thread.sleep((int) (Math.random()*2000));
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		System.out.println("["+ name + "이 결승선에 도착함");
		names.add(name);
	}
}

 

 

위 코드를 실행하는 코드

 

package thread3;


import java.util.Vector;

public class App2 {

	public static void main(String[] args) throws Exception {
		
		HorseRunnable runnable = new HorseRunnable();
		
		Thread t1 = new Thread(runnable, "번개");
		Thread t2 = new Thread(runnable, "천둥");
		Thread t3 = new Thread(runnable, "백호");
		Thread t4 = new Thread(runnable, "한라");
		Thread t5 = new Thread(runnable, "금강");
		
		System.out.println("경주를 시작합니다");
		
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		t5.start();
		
		/*
		 * join()
		 * 	- 이 메소드를 호출한 스레드가 종료될 때가지 기다려따고 남은 수행문을 실행
		 */
		t1.join();
		t2.join();
		t3.join();
		t4.join();
		t5.join();
		
		// 이 수행문을 모든 스레드의 실행이 종료될 때까지 기다렸다가 실행한다
		System.out.println("경주를 종료합니다");
		
		Vector<String> names = runnable.getnames();
		System.out.println("경기결과");
		System.out.println("1등: " + names.get(0));
		System.out.println("2등: " + names.get(1));
		System.out.println("3등: " + names.get(2));
		System.out.println("4등: " + names.get(3));
		System.out.println("5등: " + names.get(4));
		
		
	}
}

'Java' 카테고리의 다른 글

Java_익명 내부 클래스, 람다식  (0) 2024.02.26
Java_네트워크, I/O  (0) 2023.11.29
Java_I/O(입출력)  (1) 2023.11.27
Java_객체의 직렬화와 역직렬화  (1) 2023.11.26
Java_예외처리  (0) 2023.11.22