Back-End/JAVA

[JAVA] 스파르타코딩클럽 JAVA공부(5) - 프로세스와 쓰레드, 우선순위

남건욱 2023. 5. 30. 20:44
반응형
목표

수업목표는 프로세스, 쓰레드에 관해서 배우고 쓰레드를 다루는법과 자바 8에서 있었던 변화, 스트림 등을 배울 예정이다.

 

 

 

 

 

프로세스와 쓰레드의 차이

 

프로세스는 운영체제로부터 작업을 할당받는 작업의 단위이고,

쓰레드는 프로세스가 할당받은 자원을 이용하는 실행의 단위이다.

 

 

프로세스의 구조

 

쓰레드의 구조

 

 

싱글쓰레드

프로세스 안에서 하나의 쓰레드만 작동하는 것.

 

멀티쓰레드

프로세스 안에서 여러 개의 쓰레드가 작동하는 것.

 

멀티쓰레드의 장점으로는 여러 개의 쓰레드로 작업을 하여 성능이 좋아지고, 스택을 제외한 모든 영역에서 메모리를 공유하기 때문에 자원을 효율적으로 사용할 수 있다는 것이다.

 

멀티쓰레드의 단점으로는 동기화에 문제가생길수있다. 즉 충돌이 일어날수있고, 교착상태가 발생할수 있다는게 단점이다.

 

 

 

 

 

 

 

Runnable 람다식

 

public class Main {
    public static void main(String[] args) {
        Runnable task = () -> {
            int sum = 0;
            for (int i = 0; i < 50; i++) {
                sum += i;
                System.out.println(sum);
            }
            System.out.println(Thread.currentThread().getName() + " 최종 합 : " + sum);
        };

        Thread thread1 = new Thread(task);
        thread1.setName("thread1");
        Thread thread2 = new Thread(task);
        thread2.setName("thread2");

        thread1.start();
        thread2.start();
    }
}

다음 코드는 Runnable 람다식이다. Thread thread1 = new Thread(tatsk), Thread thread2 = new Thread(tatsk)에서 쓰레드 두 개를 각각 thread1, thread2 이름으로 생성해 주었다. 이때 쓰레드의 상태는 NEW상태가 되고, 아래 thread1.start(), thread2.start()을 입력하게되면 두개의 쓰레드상태가 RUNNABLE상태로 변경된다. 그 후 다시 Runnable task에 들어가 지정된 코드를 수행하고 종료된다.

 

 

 

 

 

 

 

쓰레드의 우선순위 정하기
public class Main {
    public static void main(String[] args) {
        Runnable task1 = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("$");
            }
        };

        Runnable task2 = () -> {
            for (int i = 0; i < 100; i++) {
                System.out.print("*");
            }
        };

        Thread thread1 = new Thread(task1);
        thread1.setPriority(8);
        int threadPriority = thread1.getPriority();
        System.out.println("threadPriority = " + threadPriority);

        Thread thread2 = new Thread(task2);
        thread2.setPriority(2);

        thread1.start();
        thread2.start();
    }
}

다음과 같은 코드로 쓰레드의 우선순위를 지정해 줄 수도 있다. 최소치는 1이며 최대치는 10, 보통 5로 설정한다. 쓰레드.setPriority()안에 숫자를 입력하여 우선순위를 지정해 줄 수 있고 threadPriority를 출력하면 우선순위를 확인해 볼 수 있다. 이때 주의할 점은 우선순위가 높다고 반드시 쓰레드가 먼저 종료되는 게 아니라는 것을 명심해야 한다.

 

 

 

 

 

 

쓰레드는 실행과 대기를 반복하며 run() 메서드를 수행한다. 그리고 run() 메서드가 종료되면 실행을 종료한다.

 

 

 

 

 

 

 

 

JAVA8 버전 이후의 변경점

 

 

자바는 계속 진화하고 있지만 버전 8 이후 가장 진화했다고 한다.

내가 알아야 할 변화만 간략히 찾아보았다.

 

첫 번째. 함수형 프로그래밍의 아이디어와 문법을 자바 8에서 지원한다.

두 번째. 함수형 프로그래밍의 아이디어인 (함수를 값으로 다루거나, 다른 함수에 넘길 수 있다)와 같은 일들이 가능하다.

세 번째. 함수형 프로그래밍의 문법인 익명함수 문법을 지원한다.

네 번째. 스트림이라는 컬렉션의 흐름과 같은 것을 지원한다.

다섯 번째. 스트림 기능의 지원으로 우리는 더 간결하고, 유연하고, 성능 좋은 코드를 작성할 수 있다.

 

 

 

 

 

 

 

 

스트림

 

Java 8부터 제공되는, 한번 더 추상화된 자료구조와 자주 사용하는 프로그래밍 API를 제공한 것이다. 자료구조를 한 번 더 추상화했기 때문에, 자료구조의 종류에 상관없이 같은 방식으로 다룰 수 있다. 쉽게 비유하자면, 자료구조의 흐름을 객체로 제공해 주고, 그 흐름동안 사용할 수 있는 메서드들을 api로 제공해주고 있는 것이다. 일단은 자료구조 (리스트, 맵, 셋 등)의 흐름이라고 비유하면 이해가 조금 더 쉬울 것 같다.

 

List<Car> benzParkingLot =

                carsWantToPark.stream()
                        .filter((Car car) -> car.getCompany().equals("Benz"))				.
                        .toList();

다음 코드는 스트림과 포함된 메서드들을 사용해서 구현한 기능이다.

carsWantToPark의 스트림값을 받아와서 filter() 메서드를 사용한다. 

filter() 메서드는 함수를 true/false 값을 return 하는 함수를 파라미터로 전달받고, 

(Car car) -> car.getCompany(). equals("Benz") 이구 문은 car.getCompany(). equals("Benz")를 보면 자동차의 제조사가 Benz면 true를 반환하는 함수이다. 그리고 마지막. toList()를 사용하여 결과들을 리스트로 묶어준다.

 

 

 

 

 

 

carsWantToPark.stream()
.filter((Car car) -> car.getCompany().equals("Benz"))
.toList();

간단하게 스트림을 사용하는 방법으로는 다음과 같다. 

carsWantToPark라는 메서드뒤에. stream()을 붙여주고 스트림의 값을 가져와준다.

그 후 스트림에 내가 출력해야 할 조건을 입력해 준다.

그 뒤로. toList()을 사용하여 결과를 만들어주면 된다.

 

 

 

 

 

 

 

과제

이번과제는 다수의 책들을 분류해 주고 그걸 조회해 보는 연습을 할 것이다.

기본 코드는 제공되어 있다. 여기서  5번의 조회를 할 것이고 이벤트도 구현해 볼 것이다.

 

 

 

 

package asdfasdf;

import java.util.Arrays;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Book> bookList = Arrays.asList(
                new Book(1L, "모두의 딥러닝", "조태호", "IT", 21600),
                new Book(2L, "이득우의 게임 수학", "이득우", "IT", 40500),
                new Book(3L, "자바 웹 개발 워크북", "구멍가게 코딩단", "IT", 31500),
                new Book(4L, "실전 시계열 분석", "에일린 닐슨", "IT", 34200),
                new Book(5L, "데이터 분석가의 숫자유감", "권정민", "IT", 14400),
                new Book(6L, "스프링 부트 실전 활용 마스터", "그렉 턴키스트", "IT", 25200),
                new Book(7L, "오늘부터 IT를 시작합니다", "고코더", "IT", 16200),
                new Book(8L, "그림으로 이해하는 인지과학", "기타하라 요시노리", "IT", 16200),
                new Book(9L, "괜찮아, 그 길 끝에 행복이 기다릴 거야", "손미나", "여행", 17100),
                new Book(10L, "여행의 이유", "김영하", "여행", 12150),
                new Book(11L, "여행의 시간", "김진애", "여행", 16200),
                new Book(12L, "로봇 시대 살아남기", "염규현", "역사", 14850),
                new Book(13L, "경제 전쟁의 흑역사", "이완배", "역사", 15750),
                new Book(14L, "100가지 동물로 읽는 세계사", "사이먼 반즈", "역사", 29700),
                new Book(15L, "k 배터리 레볼루션", "박순혁", "경제", 17100),
                new Book(16L, "정하준의 경제학 레시피", "장하준", "경제", 16200),
                new Book(17L, "레버리지", "롭 무어", "경제", 16200)
        );


    }
}

class Book {
    // 분류번호
    private Long id;
    // 책 이름
    private String bookName;
    // 작가 이름
    private String author;
    // 카테고리
    private String category;
    // 가격
    private double price;

    public Book(Long id, String bookName, String author, String category, double price) {
        this.id = id;
        this.bookName = bookName;
        this.author = author;
        this.category = category;
        this.price = price;
    }

    public String getBookName() {
        return bookName;
    }

    public String getCategory() {
        return category;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

제공코드는 이렇게 구현되어 있었다.

 

 

 

 

 

 

 

카테고리가 여행인 책 제목 조회

 

먼저 제공된 BookList에 stream()을 붙여주었다.

그 후 filter과정을 거치도록 만들어주었고. getCategory()을 사용하여 책카테고리를 가져와 준 뒤,. equle("여행")을 추가하여 카테고리가 여행인 것들을 가져오도록 하였다. 그 후. forEach를 사용하여 가져온 것들을 반복출력해 주도록 작성하였다. 

 

 

 

 

 

 

 

가격이 16200원 이하인 책 제목 조회

위와 마찬가지로. stream()을 생성하여 주고, filter()에서 책의 가격을 가져와준 뒤 16200원보다 작을 때의 책목록을 저장해 주었다. 그 뒤. forEach를 사용하여 getBookName()을 통하여 책의 제목을 가져와 출력해 주었다.

 

 

 

 

 

 

 

책 제목에 "경제"라는 용어가 들어간 책 제목 조회

마찬가지로 stream(),. filter()을 사용해 주었고 여기서는 '경제'가 포함되어야 해서. equals 대신. contains을 사용해 주었다. 그 후. getBookName()을 사용해서 책의 이름을 출력해 주었다.

 

 

 

 

 

 

 

가격이 가장 비싼 책 가격 조회

이 부분은 윗부분과 조금 달랐다. 먼저 double형태로 가장 비싼 값을 저장할 maxPrice라는 변수를 만들어 주었다.

그 후 bookList에. stream()을 붙여준 뒤, mapToDouble을 이용해서 Book안의 getPrice메서드를 가져와서 책의 가격을 정렬시켜 주었다. 그 후. max()을 써서 가장 높은 값을 가져온 뒤. getAsDouble();을 사용해서 저장해 주었다. 

그 뒤 maxPrice를 출력해 보면 가장 비싼 책의 금액이 출력된다.

 

 

 

 

 

 

 

카테고리가 IT인 책들의 가격 합 조회

 

bookList에. stream()을 추가해 준 뒤 필터에 book의 카테고리가 IT와 동일한 것을 가져오도록 하였다. 그 후 그것들의 책의 가격을 가져온 뒤. sum()을 사용하여 그들의 합을 구한 뒤 sum안에 저장하였다. 정상적으로 출력되는 것을 알 수 있다.

 

 

 

 

 

 

 

IT 책 할인 이벤트

 

우선 책 할인을 해주려면 List를 추가로 생성해 주었다. 리스트 이름은 discountedBookList로 지정해 주었고, 이 리스트 안에 필터를 거쳐 카테고리가 IT인 책들을 먼저 선별해 주었다. 그 후. map을 사용하여 이것들의 가격을. getPrice() * 0.6을 해주어서 40% 할인된 가격으로 저장해 준 뒤 리턴해주었다. 그 후 toList()로 리스트에 저장해 주고 출력을 해보면 정상적으로 출력된다는 것을 확인하였다.

 

 

 

 

정리

오늘 배운 내용은 생각보다 간단해 보이면서도 복잡하였다. 그동안 배운 것들이 머릿속에 잘 정리가 되지 않은 것 같다. 

오늘부로 5주 차까지 기초적인 자바문법강의가 종료되었다. 모든 주차 과정에서 과제를 할 때는 최대한 혼자 해결하려 했고, 구글검색을 최대한 활용하였다. 대부분 검색하면 나왔고 이를 잘 응용하여서 코딩에 녹여서 사용하면 해결가능한 것이 대부분이었다. 하지만 문법을 본다고 해서 코딩에 녹일방법이 쉽사리 떠오르지 않는 부분도 많았다. 계속 코딩을 하고 프로젝트를 해보면서 차근차근 알아가려 한다. 1 회독으로는 머릿속에 전부 들어오지 않아서 2 회독까지 할 예정이고, Java의 정석(기초 편) 책을 다회 독하면서 Java 코딩에 필요한 기본적인 문법을 숙지할 예정이다. 1~5주 차까지 공부하면서 짧은 시간이지만 그래도 남는 게 많았던 수업이라고 생각된다.

 

반응형
프로필사진

남건욱's 공부기록