0418_2 Enum, Thread πŸ˜‚

FiftyΒ·2025λ…„ 4μ›” 18일

2. JAVA

λͺ©λ‘ 보기
33/33

Enum: μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•œ μƒμˆ˜ μ‚¬μš© 😊

μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ΄μš©ν•œ μƒμˆ˜μ‚¬μš©μ΄ Enum의 전신이닀.
μƒμˆ˜ 선언을 ν•  λ•ŒλŠ” λ³€μˆ˜λͺ…을 λŒ€λ¬Έμžλ‘œ μ‚¬μš©ν•œλ‹€.
μΈν„°νŽ˜μ΄μŠ€ ν΄λž˜μŠ€μ— μΈμŠ€ν„΄μŠ€λŠ” κ΅¬ν˜„ν•  수 μ—†λ‹€.
μΈν„°νŽ˜μ΄μŠ€ 클래슀의 ν΄λž˜μŠ€λ³€μˆ˜λŠ” μ‚¬μš© κ°€λŠ₯ν•˜λ‹€. μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ λ³€μˆ˜λŠ” public, static이 μƒλž΅λ˜μ–΄ μžˆλ‹€.

μ‚¬λžŒλ“€μ€ μˆ«μžλ³΄λ‹€ 문자λ₯Ό μ’‹μ•„ν•œλ‹€.
μΈν„°νŽ˜μ΄μŠ€λ₯Ό 톡해 숫자λ₯Ό λ¬Έμžν™”ν•  수 μžˆλ‹€.
β†’ μ½”λ“œμ˜ 가독성 ν–₯상

μ‚¬μš© μ˜ˆμ‹œ1

package ex0418;

interface Scale {
	// νŠΉλ³„ν•œ λ©”μ†Œλ“œ 없이 μƒμˆ˜λ“€μ˜ μ§‘ν•©μ²˜λŸΌ λ§Œλ“€μ—ˆλ‹€.
	int DO = 0; int RE = 1; int MI = 2; int FA =3;
	int SO = 4; int RA = 5; int TI = 6;
}

public class InterfaceBaseConstTest {
	public static void main(String[] args) {
		int sc = Scale.DO;
		
		switch(sc) {
		case Scale.DO:
			System.out.println("도");
			break;
		case Scale.RE:
			System.out.println("레");
			break;
		case Scale.MI:
			System.out.println("λ―Έ");
			break;
		case Scale.FA:
			System.out.println("파");
			break;
		case Scale.SO:
			System.out.println("솔");
			break;
		case Scale.RA:
			System.out.println("라");
			break;
		case Scale.TI:
			System.out.println("μ‹œ");
			break;
		}
	}
}

μ‚¬μš© μ˜ˆμ‹œ2

package ex0418;

interface Animal{
	int DOG = 1;
	int CAT = 2;
}

interface Person{
	int MAN = 1;
	int WOMAN = 2;
}
public class NonsafeConst {

	public static void main(String[] args) {
		who(Person.MAN);
		who(Person.WOMAN);
	}

	public static void who(int man) {
		switch(man) {
		case Person.MAN: System.out.println("남성 μ†λ‹˜μž…λ‹ˆλ‹€."); break;
		case Person.WOMAN: System.out.println("μ—¬μ„± μ†λ‹˜μž…λ‹ˆλ‹€."); break;
		}
	}
}

who(Animal.DOG); λ₯Ό 해도 남성 μ†λ‹˜μž…λ‹ˆλ‹€. 라고 좜λ ₯ β†’ μ›ν•˜μ§€ μ•ŠλŠ” 데이터&κ²°κ³Όκ°’

ENUM μ‚¬μš©

package ex0418;

enum Scale1{
	DO, RE, MI, FA, SO, RA, TI
}

public class SimpleEnumTest {

	public static void main(String[] args) {

		Scale1 sc = Scale1.DO;
		System.out.println(sc);
		
		switch(sc) {
			case DO: System.out.println("도"); break;
			case RE: System.out.println("레"); break;
			case MI: System.out.println("λ―Έ"); break;
			case FA: System.out.println("파"); break;
			case SO: System.out.println("솔"); break;
			case RA: System.out.println("라"); break;
			case TI: System.out.println("μ‹œ"); break;
		}
	}
}

interface둜 μž‘μ„±ν•œ 것(μ‚¬μš©μ˜ˆμ‹œ1)과의 차이점

  1. Scale1{} 내에 μžλ£Œν˜• 없이 λ³€μˆ˜λͺ…λ§Œ μ„ μ–Έ
  2. sc의 νƒ€μž…μ΄ intκ°€ μ•„λ‹Œ enumλͺ…
  3. case λ³€μˆ˜λͺ…: 클래슀λ₯Ό 톡해 μ ‘κ·Όν•˜μ§€ μ•ŠλŠ”λ‹€.
package ex0418;

enum Animal1{
	DOG, CAT
}
enum Person1{
	MAN, WOMAN
}

public class SafeEnumTest {

	public static void main(String[] args) {

		who(Person1.MAN);
		
	}
	
	public static void who(Person1 man) {
		switch(man) {
		case MAN: System.out.println("λ‚¨μ„±μž…λ‹ˆλ‹€.");
		case WOMAN: System.out.println("μ—¬μ„±μž…λ‹ˆλ‹€.");
		}
	}

}

interface둜 μž‘μ„±ν•œ 것(μ‚¬μš©μ˜ˆμ‹œ2)과의 차이점

Person1을 μžλ£Œν˜•μ²˜λŸΌ μ‚¬μš© κ°€λŠ₯
κ·Έλž˜μ„œ Animal은 μ œν•œλ˜μ–΄ who ν•¨μˆ˜μ— λ“€μ–΄κ°ˆ 수 μ—†λ‹€.

ν΄λž˜μŠ€μ™€μ˜ 비ꡐ

package ex0418;

enum Human3{
	MAN, WOMAN;
	
	private Human3() {
		System.out.println("Human constructor called...");
	}
}

public class EnumConstTest {

	public static void main(String[] args) {

		System.out.println(Human3.MAN);
		System.out.println(Human3.WOMAN);
	}

}

κ²°κ³Ό: κΈ°λ³Έμƒμ„±μžλ‘œ λ™μž‘

Human constructor called...
Human constructor called...
MAN
WOMAN

μ œμ•½μ„ κ±Έ μˆ˜λ„ μžˆλ‹€.

package ex0418;

enum Person3{
	MAN(29), WOMAN(32);
	
	int age;
	
	private Person3(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "I am " + age + "years old";
	}
}

public class EnumParamConstructorTest {

	public static void main(String[] args) {

		System.out.println(Person3.MAN);
		System.out.println(Person3.WOMAN);
	}
}

μ‚¬μš© 예제3

package ex0418;

enum Day{
	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumTest1 {

	public static void main(String[] args) {

		Day today = Day.FRIDAY;
		System.out.println(today);
		
		for(Day d:Day.values()) {
			System.out.println(d);
		}
		
		switch(today) {
		case MONDAY:
			System.out.println("또 ν•œμ£Όκ°€ μ‹œμž‘λ˜μ—ˆκ΅°");
			break;
		case TUESDAY:
			System.out.println("μ–Έμ œ μ˜€λ‚˜ 주말..");
			break;
		case WEDNESDAY:
			System.out.println("였늘만 κ°€λ©΄ 2일 λ‚¨μ•˜λ‹€.");
			break;
		case THURSDAY:
			System.out.println("이제 λ‚΄μΌλ§Œ..");
			break;
		case FRIDAY:
			System.out.println("이제 였늘만..");
			break;
		case SATURDAY:
			break;
		case SUNDAY:
			break;
		default:
				
		}
	}
}

μ΄λ ‡κ²Œλ„ μ‚¬μš© κ°€λŠ₯

package ex0418;

enum Day{
	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumTest1 {

	public static void main(String[] args) {

		Day today = Day.FRIDAY;
		System.out.println(today);
		
		for(Day d:Day.values()) {
			System.out.println(d);
		}
		
		switch(today) {
		case MONDAY -> System.out.println("또 ν•œμ£Όκ°€ μ‹œμž‘λ˜μ—ˆκ΅°");
		case TUESDAY -> System.out.println("μ–Έμ œ μ˜€λ‚˜ 주말..");
		case WEDNESDAY -> System.out.println("였늘만 κ°€λ©΄ 2일 λ‚¨μ•˜λ‹€.");
		case THURSDAY -> System.out.println("이제 λ‚΄μΌλ§Œ..");
		case FRIDAY ->	System.out.println("이제 였늘만..");
		case SATURDAY -> System.out.println("툐였일");
		case SUNDAY ->	System.out.println("주말 끝");
		default -> System.out.println("뭐야");				
		}
	}
}
package ex0418;

enum Day{
	MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumTest1 {

	public static void main(String[] args) {

		Day today = Day.FRIDAY;
		System.out.println(today);
		
		switch(today) {
		case SATURDAY -> System.out.println("툐였일");
		case SUNDAY ->	System.out.println("μΌμš”μΌ");
		default -> System.out.println("평일");				
		}
	}
}

Enum을 ν™œμš©ν•œ νšŒμ›μ •λ³΄(이름, 성별) 관리

성별은 enum으둜 male, female

Member.java

package ex0418;

import lombok.Data;

enum Gender{
	MALE, FEMALE;
}

@Data
public class Member {
	String name;
	Gender gender;
	
	Member(){}
	
	Member(String name, Gender gender){
		this.name=name;
		this.gender=gender;
	}
}

MemberTest.java

package ex0418;

public class MemberTest {

	public static void main(String[] args) {

		Member m1 = new Member();
		m1.setName("홍길동");
		m1.setGender(Gender.MALE);
		System.out.println(m1);
		
		Member m2 = new Member("심청이", Gender.FEMALE);
		System.out.println(m2);
	}
}

κ²°κ³Ό

Member(name=홍길동, gender=MALE)
Member(name=심청이, gender=FEMALE)

μ°Έκ³ 

		System.out.println(m1.getGender());	// String νƒ€μž…μΈκ°€ν–ˆμ§€λ§Œ
		Gender g = m1.getGender();			// λ°˜ν™˜νƒ€μž…μ€ Gender
		System.out.println(g.toString());	// toStringμœΌλ‘œλ„ κ°€λŠ₯, μžλ™μ μœΌλ‘œ νƒ€μž…λ³€ν™˜

μ‚¬μš© 예제4

Enum Day2.java

package ex0418;

public enum Day2 {

	// 각 μƒμˆ˜μ— ν•œκΈ€ 이름과 μ˜μ–΄ 이름을 λΆ€μ—¬
	MONDAY("μ›”μš”μΌ","Monday"),
	TUESDAY("ν™”μš”μΌ","Thesday"),
	WEDNESDAY("μˆ˜μš”μΌ","Wednesday"),
	THURSDAY("λͺ©μš”일","Thursday"),
	FRIDAY("κΈˆμš”μΌ","Friday"),
	SATURDAY("ν† μš”μΌ","Saturday"),
	SUNDAY("μΌμš”μΌ","Sunday");
	
	private final String korName;
	private final String engName;
	
	Day2(String korName, String engName){
		this.korName=korName;
		this.engName=engName;
	}
	
	public String getKorName() {
		return korName;
	}
	
	public String getEngName() {
		return engName;
	}
}

Main.java

package ex0418;

public class Day2Test {

	public static void main(String[] args) {

		for(Day2 d:Day2.values()) // values()λŠ” Day2νƒ€μž…μ˜ 배열이닀.
			System.out.println(d + ":" + d.getKorName() + "," + d.getEngName());
		
        Day2 today = Day2.FRIDAY;
		System.out.println("μ˜€λŠ˜μ€"+today.getKorName()+"μž…λ‹ˆλ‹€.");
		System.out.println("Today is"+today.getEngName()+"μž…λ‹ˆλ‹€.");
	}

}

νšŒμ› 클래슀 λ§Œλ“€κΈ°

클래슀λͺ…: User
λ©€λ²„λ³€μˆ˜: νšŒμ›λ²ˆν˜Έ, 이름, 성별, νšŒμ›λ“±κΈ‰
성별: λ‚¨μž(MALE), μ—¬μž(FEMALE)
νšŒμ›λ“±κΈ‰: κ³¨λ“œ(GOLD), 싀버(SILVER), 브둠즈(BRONZE)
νšŒμ›λ“±κΈ‰μ΄ κ³¨λ“œμΈ νšŒμ›μ€ ν• μΈμœ¨μ΄ 10% μ μš©λ©λ‹ˆλ‹€.
νšŒμ›λ“±κΈ‰μ΄ 싀버인 νšŒμ›μ€ ν• μΈμœ¨μ΄ 5% μ μš©λ©λ‹ˆλ‹€.
νšŒμ›λ“±κΈ‰μ΄ 브둠즈인 νšŒμ›μ€ ν• μΈμœ¨μ΄ 2% μ μš©λ©λ‹ˆλ‹€.
νšŒμ›λ“±κΈ‰μ„ enum으둜 λ§Œλ“œμ‹œμ˜€.
enum의 λ©€λ²„μƒμˆ˜λŠ” korName(String), discountRate(double)둜 ν•œλ‹€.
μ‹€ν–‰ν΄λž˜μŠ€λ₯Ό λ§Œλ“€μ–΄ κ³¨λ“œ, 싀버, 브둠즈 νšŒμ›μ„ ν…ŒμŠ€νŠΈ ν•˜μ‹œμ˜€.

μΆ”κ°€

enum에 calculateDiscount()λ©”μ†Œλ“œλ₯Ό λ§Œλ“œμ‹œμ˜€
등급별 ν• μΈμœ¨μ„ μ μš©ν•˜μ—¬ 할인 κΈˆμ•‘μ„ λ°˜ν™˜ν•˜λŠ” λ©”μ†Œλ“œ
int calculateDiscount(int price)
User ν΄λž˜μŠ€μ— pay()λ©”μ†Œλ“œλ₯Ό λ§Œλ“œμ‹œμ˜€
void pay(int price)
νšŒμ›λ“±κΈ‰κ³Ό μ‹€μ œ μ§€λΆˆν•œ κΈˆμ•‘μ„ μ½˜μ†”μ— 좜λ ₯ν•˜λŠ” κΈ°λŠ₯
예) κ³¨λ“œνšŒμ› JamesλŠ” 180000원을 μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€. price = 200000 - discount10%(20000) = 180000

UserTest.java(Main)

package ex0418;

public class UserTest {

	public static void main(String[] args) {

		User u1 = new User();
		u1.setUNo(1);
		u1.setName("James");
		u1.setGender(Gender.MALE);
		u1.setLevel(Level.GOLD);
		
		System.out.println(u1.getUNo()+"번 νšŒμ› 이름: "+u1.getName()
				+", 성별: "+u1.getGender().getGender()
				+", λ“±κΈ‰: "+u1.getLevel()
				+", ν• μΈμœ¨: "+u1.getLevel().getDiscountRate());

		u1.pay(200000);
	}
}

User.java

package ex0418;

import lombok.Data;

@Data
public class User {
	private int uNo;
	private String name;
	private Gender gender;
	private Level level;

	/*
	public void pay(int price) {
		//int discount = level.calculateDiscount(price);
		System.out.println(level.getKorName()+"νšŒμ› "+name+"λŠ” "
		+(price-level.calculateDiscount(price))+"λ₯Ό μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€."
		+" | 할인받은 κΈˆμ•‘: "+level.calculateDiscount(price));
	}
    */
    public void pay(int price) {
		System.out.printf(level.getKorName()+"νšŒμ› "+name+"λŠ” "
				+"%,d원을 μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€."
				+" | 할인 받은 κΈˆμ•‘: %,d원",price-level.calculateDiscount(price),level.calculateDiscount(price));
	}
	
	@Override
	public String toString() {
		return getUNo()+"번 νšŒμ› 이름: "+getName()
		+", 성별: "+getGender().getGender()
		+", λ“±κΈ‰: "+getLevel()
		+", ν• μΈμœ¨: "+getLevel().getDiscountRate();
	}
    
    
}

Gender.java

package ex0418;

public enum Gender {
	MALE("λ‚¨μž"), FEMALE("μ—¬μž");
	
	private final String gender;
	
	Gender(String gender){
		this.gender=gender;
	}
	
	public String getGender() {
		return gender;
	}
}

Level.java

package ex0418;

public enum Level {
	GOLD("κ³¨λ“œ",10), SILVER("싀버",5), BRONZE("브둠즈",2);
	
	private final String korName;
	private final double discountRate;
	
	Level(String korName, double discountRate){
		this.korName=korName;
		this.discountRate=discountRate;
	}
	
	public String getKorName() {
		return korName;
	}
	
	public double getDiscountRate() {
		return discountRate;
	}
	
	public int calculateDiscount(int price) {
		return price * (int)discountRate/100;
	}
}

κ²°κ³Ό

1번 νšŒμ› 이름: James, 성별: λ‚¨μž, λ“±κΈ‰: GOLD, ν• μΈμœ¨: 10.0
κ³¨λ“œνšŒμ› JamesλŠ” 180000λ₯Ό μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€.| 할인받은 κΈˆμ•‘: 20000

κΈˆμ•‘μ„ 읽기가 μ–΄λ €μ›Œμ„œ printf("%,d",price)ν˜•μ‹μœΌλ‘œ λ³€κ²½ν–ˆλ‹€.
μ‚¬μš©μž 정보λ₯Ό 좜λ ₯ν•˜λŠ” toString을 Overrideν–ˆλ‹€.

		System.out.printf(level.getKorName()+"νšŒμ› "+name+"λŠ” "
				+"%,d원을 μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€."
				+"| 할인 받은 κΈˆμ•‘: %,d원",price-level.calculateDiscount(price),level.calculateDiscount(price));

κ²°κ³Ό

κ³¨λ“œνšŒμ› JamesλŠ” 180,000원을 μ§€λΆˆν–ˆμŠ΅λ‹ˆλ‹€. | 할인 받은 κΈˆμ•‘: 20,000원

Thread

ν”„λ‘œμ„ΈμŠ€

μ‹€ν–‰ 쀑인 ν”„λ‘œκ·Έλž¨, ν•˜λ‚˜μ˜ ν”„λ‘œμ„ΈμŠ€λŠ” ν•˜λ‚˜ μ΄μƒμ˜ μ“°λ ˆλ“œλ₯Ό κ°–λŠ”λ‹€.

Multi Thread

λ³‘λ ¬μ²˜λŸΌ λŠκ»΄μ§€μ§€λ§Œ ν•œ 개의 CPU의 μ‚¬μš©μ„ 짧은 μ‹œκ°„μ— λΉ λ₯΄κ²Œ νšŒμ „ν•¨μ„ 톡해 λ™μ‹œμ„±μ„ κ΅¬ν˜„ν•¨

Threadλ₯Ό λ§Œλ“œλŠ” 방법

  1. Thread 클래슀λ₯Ό μƒμ†λ°›λŠ”λ‹€. λ°˜λ“œμ‹œ κ΅¬ν˜„ν•΄μ•Όν•˜λŠ” λ©”μ„œλ“œ: run()
    1λ²ˆμ€ 잘 μ•ˆμ“΄λ‹€. ν΄λž˜μŠ€λŠ” 상속을 ν•˜λ‚˜λ§Œ 받을 수 μžˆλŠ”λ°, λ‹€λ₯Έ 클래슀λ₯Ό 상속받을 수 μ—†κΈ° λ•Œλ¬Έ.
  2. Interface둜 κ΅¬ν˜„ν•˜κΈ°(Runnable)

문제점(μ‚¬μš© 이유)

두 개 μ΄μƒμ˜ Threadκ°€ 곡용 μžμ›μ„ μ‘°μž‘ν•˜λ €κ³  ν•  λ•Œ, μ—°μ‚° μˆœμ„œλ₯Ό μ œμ–΄ν•  ν•„μš”κ°€ μžˆλ‹€.

1. Thread 상속받기

MyThread.java

package ex0418;

public class MyThread extends Thread{
	@Override
	public void run() {
		for(int i=0; i<10; i++) {
			System.out.println(Thread.currentThread().getName() + ": " + i);	// ν˜„μž¬ 싀행쀑인 Thread의 이름을 μ–»κΈ°
			
			try {
				Thread.sleep(1000);		// 1초 κ°„ Threadλ₯Ό λ©ˆμΆ˜λ‹€. 1000=1초
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

MyThreadTest.java(Main)

package ex0418;

public class MyThreadTest {

	public static void main(String[] args) {

		MyThread t1 = new MyThread();
		t1.setName("Thread-A");
		t1.start();	// run()을 직접 ν˜ΈμΆœν•˜λ©΄ μ•ˆλœλ‹€.
        System.out.println("----End of Main----");
	}
}

κ²°κ³Ό: 1μ΄ˆλ§ˆλ‹€ 계속 μŒ“μΈλ‹€.(10개)

----End of Main----
Thread-A: 0
Thread-A: 1
Thread-A: 2
Thread-A: 3
Thread-A: 4
Thread-A: 5
Thread-A: 6
Thread-A: 7
Thread-A: 8
Thread-A: 9

μ‹€ν–‰ μ‹œκ°„μ΄ 10.444초둜 ν™•μΈλ˜μ—ˆλ‹€.
Threadλ₯Ό μ‹€ν–‰ν•˜κ³ , λ‹€μŒ printλ₯Ό μ‹€ν–‰ν–ˆμœΌλ‚˜ printκ°€ λ¨Όμ € λλ‚˜κ³  Threadκ°€ 끝났닀.
ThreadλŠ” λ…μžμ μ΄λΌ Main이 끝났닀고 λλ‚˜μ§€ μ•ŠλŠ”λ‹€.

t2λ₯Ό ν•˜λ‚˜ 더 λ§Œλ“€μ–΄μ„œ 비ꡐ

package ex0418;

public class MyThreadTest {

	public static void main(String[] args) {

		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		t1.setName("Thread-A");
		t2.setName("Thread-B");
		
		t1.start();	// run()을 직접 ν˜ΈμΆœν•˜λ©΄ μ•ˆλœλ‹€.
		t2.start();
		
		System.out.println("----End of Main----");
	}
}

κ²°κ³Ό: A와 Bκ°€ 같은 μ‹œμ μ— λ™μž‘ν•˜κ³  있음.

----End of Main----
Thread-A: 0
Thread-B: 0
Thread-A: 1
Thread-B: 1
Thread-B: 2
Thread-A: 2
Thread-A: 3
Thread-B: 3
Thread-B: 4
Thread-A: 4
Thread-A: 5
Thread-B: 5
Thread-A: 6
Thread-B: 6
Thread-A: 7
Thread-B: 7
Thread-B: 8
Thread-A: 8
Thread-A: 9
Thread-B: 9

2. μΈν„°νŽ˜μ΄μŠ€(Runnable)둜 κ΅¬ν˜„ν•˜κΈ°

MyRunnable.java

package ex0418;

public class MyRunnable implements Runnable{
	
	public void run() {
		for(int i=0; i<10; i++) {
			System.out.println(Thread.currentThread().getName()+": "+i);
			
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
}

MyRunnableTest.java(Main)

package ex0418;

public class MyRaunnableTest {

	public static void main(String[] args) {

		MyRunnable runnable = new MyRunnable();
	
		Thread t1 = new Thread(runnable, "Thread-A");
		Thread t2 = new Thread(runnable, "Thread-B");
		
		t1.start();
		t2.start();
	}
}

λ§Œμ•½ start()κ°€ μ•„λ‹Œ run()을 μ‹€ν–‰ν•˜λ©΄ main이 두 개의 μ“°λ ˆλ“œλ₯Ό μ‹€ν–‰μ‹œν‚¨ λͺ¨μŠ΅μ΄ λœλ‹€.

main: 0
main: 1
main: 2
main: 3
main: 4
main: 5
main: 6
main: 7
main: 8
main: 9
main: 0
main: 1
main: 2
main: 3
main: 4
main: 5
main: 6
main: 7
main: 8
main: 9
package ex0418;

public class ProblemOfThread {

	public static int money = 0;
	
	public static void main(String[] args) throws InterruptedException {
		Runnable task1 = () -> {
			for(int i=0; i<10000; i++) {
				money++;
			}
		}; // μ΄κ²ƒλ§κ³ λŠ” κ΅¬ν˜„ν•  것이 μ—†μ–΄μ„œ λžŒλ‹€μ‹μœΌλ‘œ μž‘μ„±
		
		Runnable task2 = () -> {
			for(int i=0; i<10000; i++) {
				money--;
			}
		};
		
		Thread t1 = new Thread(task1);
		Thread t2 = new Thread(task2);
		
		t1.start();
		t2.start();
		
		t1.join();
		t2.join();
		
		System.out.println(money);
	}
}

join()ν•˜κΈ° μ „ κ²°κ³Ό: 0
join()ν•œ λ’€ κ²°κ³Ό: -6849 or 8792 λ“± μ‹€ν–‰ν•  λ•Œλ§ˆλ‹€ λ‹€λ₯Έ 값이 λ‚˜μ˜΄
β†’ κ³΅μœ μžμ›μ— 두 개 μ΄μƒμ˜ Threadκ°€ μ ‘κ·Όν•  경우 μƒκΈ°λŠ” λ¬Έμ œλ‹€.

동기화 β†’ synchronized

λ™μ‹œμ„±μ„ 제거 β†’ 쀄 μ„Έμš°κΈ° β†’ 동기화 : μˆœμ„œλŒ€λ‘œ μ‹€ν–‰λ˜λŠ” 것
*ThreadλŠ” 비동기

package ex0418;

public class SyncMethodTest {

	public static int money = 0;
	
	public static void main(String[] args) throws InterruptedException {

		Runnable task1 = () -> {
			for(int i=0; i<10000; i++)
				deposit();
		};
		
		Runnable task2 = () -> {
			for(int i=0; i<10000; i++)
				withdraw();
		};
		
		Thread t1 = new Thread(task1);
		Thread t2 = new Thread(task2);
		
		t1.start();
		t2.start();
		
		t1.join();
		t2.join();

		System.out.println(money);
	}
	
	// λ™μ‹œμ„± λ•Œλ¬Έμ— μƒκΈ°λŠ” λ¬Έμ œμ΄λ―€λ‘œ λ™μ‹œμ„±μ„ μ—†μ•€λ‹€.
	// deposit()이 moneyλ₯Ό 만질 λ•ŒλŠ” withdraw()κ°€ κ±΄λ“œλ¦¬λ©΄ μ•ˆλœλ‹€. β†’ μ€„μ„Έμš΄λ‹€. β†’ 동기화
	// β†’ synchronized
	public synchronized static void deposit() {
		money++;
	}

	public synchronized static void withdraw() {
		money--;
	}
}

3.

0개의 λŒ“κΈ€