Java 13일차

소윤정·2021년 6월 10일
0

JAVA

목록 보기
12/15

이제 국비지원 학원을 다닌지 2주가 넘어가고 있다. 자바는 이제 슬슬 마무리 단계이다! 오늘은 자바 마지막 수업에 대해 정리를 해보려한다.

Runnable 인터페이스

  • 구현할 메소드가 run() 하나뿐인 함수형 인터페이스.
  • 자바는 한개 이상의 클래스를 상속받을 수 없는데, Runnable 인터페이스를 이용하여 상속(implements)받은 자식 클래스는 다른 클래스를 상속 받을 수 있다.

Thread를 생성하는 방법

  1. Thread 클래스 상속
public class PrintThread1  extends  Thread {
    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            if(i%2 == 0){
                System.out.println("PrintThread1 : " + i);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

  1. Runnable 인터페이스를 구현
public class 클래스명 implements Runnable{
	public void run(){
		// 필수로 구현
		// 작업 구간...
        	Runnable 참조변수명 = new 생성자();
        	참조변수명.start();
	}
}

예제)

public class PrintThread2 implements  Runnable {

    @Override
    public void run() {
        for(int i = 0; i < 10; i++){
            if(i%2 == 0){
                System.out.println("⭐️  PrintThread2 : " + i);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
  1. 익명 클래스를 사용
    (굉장히 많이 사용하므로 알아두는 것이 좋다.)
/*
    1,2번 메인
 */
public class Main1 {
    public static void main(String[] args) {
        Thread th1 = new PrintThread1();
        Runnable r1 = new PrintThread2();
        Thread th2 = new Thread(r1);

        Thread th3 = new Thread(new Runnable() { // 익명클래스
            @Override
            public void run() {
                for(int i = 0; i < 10; i++){
                    if(i%2 == 0){
                        System.out.println("🎁 익명 클래스 : " + i);
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

        Thread th4 = new Thread(() -> { // 람다식
            for(int i = 0; i < 10; i++){
                if(i%2 == 0){
                    System.out.println("✅ 람다를 이용한 익명 클래스 : " + i);
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        // 메인도 쓰레드이다.
        for(int i = 0; i < 10; i++){ // 메인이 먼저 돌고 나머지 메소드들이 실행
            if(i%2 == 0){
                System.out.println("🐶 메인 : " + i);
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        th1.start();
        th2.start();
        th3.start();
        th4.start();
    }
}

Thread 우선 순위

  • main 쓰레드가 가장 우선위가 높다.
  • main 쓰레드보다 우선순위를 높게 주려면 join()(예외처리 필수) 메소드를 사용

람다 표현식

  • 프로그래밍 언어에서 사용되는 개념으로 익명 함수(Anonymous Functions)를 지칭하는 용어
    익명함수란?
    • 말그대로 함수의 이름이 없는 함수로, 익명함수들은 공통적으로 일급 객체(First class citizen)라는 특징을 가지고 있다.
    • 일급 객체란 일반적으로 다른 객체들에 적용 가능한 연산을 모두 지원하는 개체를 가르킨다. 함수를 값으로 사용할 수도 있으며 파라미터로 전달 및 변수에 대입하기와 같은 연산들이 가능하다.

표현 방법

  1. 람다는 매개변수 화살표(->) 함수 몸체로 이용하여 사용할 수 있다.
  2. 함수 몸체가 단일 실행문이면 괄호{}를 생략할 수 있다.
  3. 함수 몸체가 return 문으로만 구성되어 있는 경우 괄호{}를 생략할 수 없다.
Calc calc = (x,y) -> x < y ? x : y;

public class Calc{
	public int func1(x,y){
		int result = x < y? x : y;
		return result;
	}
}

예제)

interface Compare{
    public int compartTo(int a, int b);
}

public class Lambda2 {
    public static void exec(Compare com){
        int num1 = 10;
        int num2 = 20;
        int result = com.compartTo(num1, num2);
        System.out.println(result);
    }

    public static void main(String[] args) {
        exec((i, j) -> {
            return  i + j;
        });

        exec((i, j) -> {
            return  i * j;
        });
    }
}

동기화(synchronized)

  • 멀티 쓰레드 프로세스에서는 다른 쓰레드의 작업에 영향을 미칠 수 있기 때문에, 진행 중인 작업이 다른 쓰레드에 간섭 받지 않게 하려면 동기화가 필요
  • 동기화를 하려면 간섭받지 않아야 하는 문장들은 '임계영역'으로 설정하며, 임계영역은 락(lock)을 얻은 단 하나의 쓰레드만 출입이 가능하다.
  • wait() : 쓰레드 대기
  • notify() : 쓰레드 재시작

연습문제

ATM기를 이용하여 출금되는 프로그램을 만들어보자.
ATM.java

public class ATM implements Runnable{
    private int money = 1000000;

    // 메소드 동기화
    public synchronized void withdraw(int money){ // 출금
        this.money -= money;
        System.out.println(Thread.currentThread().getName() + "가" + money + "원 출금 ✅"); // 현재 쓰레드의 이름
        System.out.println("잔액 : " + this.money + "원");
    }


    @Override
    public void run() {
//        synchronized (this){
            for(int i =0; i < 10; i++){
                withdraw(10000);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
//        }
    }
}

Main.java

public class Main3 {
    public static void main(String[] args) {
        ATM kbbank = new ATM();

        Thread apple = new Thread(kbbank, "김사과");
        Thread banana = new Thread(kbbank, "반하나"); // 쓰레드 객체 생성

        apple.start();
        banana.start();
    }
}

이것을 마지막으로 자바수업이 끝이나게되었다. 그다음 수업은 SQL 수업하고 나중에 자바랑 연동한다 그러니 자바 문법을 잊어버리지 않도록 틈틈히 연습문제를 풀어보면서 감을 잃지 않아야겠다.

0개의 댓글

관련 채용 정보