CodeGym /Java Blog /무작위의 /자바의 멀티스레딩
John Squirrels
레벨 41
San Francisco

자바의 멀티스레딩

무작위의 그룹에 게시되었습니다
안녕! 우선, 축하합니다. Java의 다중 스레딩 주제에 도달했습니다! 이것은 중대한 성과입니다. 여러분은 먼 길을 왔습니다. 그러나 스스로 준비하십시오. 이것은 코스에서 가장 어려운 주제 중 하나입니다. 여기서는 복잡한 클래스나 많은 메서드를 사용하는 것이 아닙니다. 실제로는 20개 미만을 사용합니다. 생각하는 방식을 조금 바꿔야 할 것입니다. 이전에는 프로그램이 순차적으로 실행되었습니다. 어떤 코드 줄은 다른 줄 다음에 나왔고, 어떤 메서드는 다른 줄 뒤에 나왔고, 모든 것이 기본적으로 명확했습니다. 먼저 무언가를 계산한 다음 결과를 콘솔에 표시한 다음 프로그램이 종료되었습니다. 멀티스레딩을 이해하려면 병렬성 측면에서 생각하는 것이 좋습니다. 매우 간단한 것부터 시작하겠습니다. ) 가족이 한 집에서 다른 집으로 이사한다고 상상해 보십시오. 모든 책을 모으는 것이 이사의 중요한 부분이 될 것입니다. 당신은 책을 많이 모아서 상자에 넣어야 합니다. 현재, 당신은 유일한 사람입니다. 엄마는 음식을 준비하고, 오빠는 옷을 싸고, 언니는 가게에 갔다. 혼자서 어떻게든 해낼 수 있습니다. 조만간 스스로 작업을 완료하겠지만 시간이 많이 걸릴 것입니다. 그러나 당신의 여동생은 20분 후에 가게에서 돌아올 것이고 그녀는 할 일이 없습니다. 그래서 그녀는 당신과 함께 할 수 있습니다. 작업은 변경되지 않았습니다. 책을 상자에 넣습니다. 하지만 두 배 빠르게 수행되고 있습니다. 왜? 작업이 동시에 진행되기 때문입니다. 두 개의 서로 다른 '스레드'(귀하와 여동생)가 동일한 작업을 동시에 수행하고 있습니다. 그리고 아무것도 바뀌지 않는다면, 그러면 모든 것을 혼자 하는 상황에 비해 엄청난 시차가 있을 것입니다. 형제가 곧 일을 마치면 그는 당신을 도울 수 있고 일이 더 빨리 진행될 것입니다.

멀티스레딩으로 해결되는 문제

멀티스레딩은 실제로 두 가지 중요한 목표를 달성하기 위해 발명되었습니다.
  1. 동시에 여러 가지 작업을 수행합니다.

    위의 예에서 서로 다른 스레드(가족 구성원)는 여러 작업을 병렬로 수행했습니다. 설거지, 가게에 가기, 물건 포장하기 등이 있습니다.

    프로그래밍과 더 밀접하게 관련된 예를 제공할 수 있습니다. 사용자 인터페이스가 있는 프로그램이 있다고 가정합니다. 프로그램에서 '계속'을 클릭하면 일부 계산이 수행되고 사용자는 다음 화면을 보게 됩니다. 이러한 작업이 순차적으로 수행되면 사용자가 '계속' 버튼을 클릭한 후 프로그램이 중단됩니다. 사용자는 프로그램이 모든 내부 계산을 수행하고 사용자 인터페이스가 새로 고쳐지는 부분에 도달할 때까지 '계속' 버튼 화면이 있는 화면을 보게 됩니다.

    글쎄, 우리는 몇 분 기다릴 것 같아요!

    Java의 멀티스레딩: 정의, 이점 및 일반적인 함정 - 3

    또는 프로그램을 재작업하거나 프로그래머가 말하는 것처럼 '병렬화'할 수 있습니다. 한 스레드에서 계산을 수행하고 다른 스레드에서 사용자 인터페이스를 그려봅시다. 대부분의 컴퓨터에는 이 작업을 수행할 수 있는 충분한 리소스가 있습니다. 이 경로를 택하면 프로그램이 중단되지 않고 사용자가 내부에서 일어나는 일에 대해 걱정하지 않고 화면 사이를 원활하게 이동할 수 있습니다. 하나는 다른 하나를 방해하지 않습니다 :)

  2. 더 빠르게 계산을 수행합니다.

    여기서 모든 것이 훨씬 간단합니다. 프로세서에 여러 개의 코어가 있고 오늘날 대부분의 프로세서에 있는 경우 여러 코어가 작업 목록을 병렬로 처리할 수 있습니다. 분명히 우리가 1000개의 작업을 수행해야 하고 각각 1초가 걸린다면 하나의 코어는 1000초 안에, 두 개의 코어는 500초 안에, 세 개의 코어는 333초보다 약간 더 많은 시간에 목록을 완료할 수 있습니다.

그러나 이 강의에서 이미 읽었듯이 오늘날의 시스템은 매우 스마트하며 하나의 컴퓨팅 코어에서도 작업이 번갈아 수행되는 병렬 처리 또는 유사 병렬 처리를 달성할 수 있습니다. 일반 사항을 세부 사항으로 이동하고 Java 멀티스레딩 라이브러리에서 가장 중요한 클래스인 java.lang.Thread에 대해 알아봅시다. 엄밀히 말하면 Java 스레드는 Thread 클래스 의 인스턴스로 표시됩니다 . 즉, 10개의 스레드를 만들고 실행하려면 이 클래스의 인스턴스가 10개 필요합니다. 가장 간단한 예를 작성해 보겠습니다.

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("I'm Thread! My name is " + getName());
   }
}
스레드를 만들고 실행하려면 클래스를 만들고 java.lang 을 상속해야 합니다 . 클래스를 스레드 하고 해당 run() 메서드를 재정의합니다. 마지막 요구 사항은 매우 중요합니다. 스레드가 실행할 논리를 정의하는 것은 run() 메서드 에 있습니다 . 이제 MyFirstThread 의 인스턴스를 만들고 실행하면 run () 메서드는 이름이 있는 줄을 표시합니다. getName() 메서드는 자동으로 할당되는 스레드의 '시스템' 이름을 표시합니다. 그런데 왜 우리는 잠정적으로 말하고 있습니까? 하나를 만들고 알아보자!

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {

           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
콘솔 출력: 저는 Thread입니다! 제 이름은 Thread-2입니다. 저는 Thread입니다! 제 이름은 Thread-1입니다. 저는 Thread입니다! 제 이름은 Thread-0입니다. 저는 Thread입니다! 제 이름은 Thread-3입니다. 저는 Thread입니다! 제 이름은 Thread-6입니다. 저는 Thread입니다! 제 이름은 Thread-7입니다. 저는 Thread입니다! 제 이름은 Thread-4입니다. 저는 Thread입니다! 제 이름은 Thread-5입니다. 저는 Thread입니다! 제 이름은 Thread-9입니다. 저는 Thread입니다! 내 이름은 Thread-8입니다. 10개의 스레드( Thread 를 상속하는 MyFirstThread 개체 ) 를 만들고 각 개체에 대해 start() 메서드를 호출하여 스레드를 시작하겠습니다 . start() 메서드를 호출한 후 run() 메서드 의 논리가 실행됩니다. 참고: 스레드 이름은 순서가 없습니다. 그들이 순차적으로 그렇지 않은 것이 이상합니다., Thread-1 , Thread-2 등? 공교롭게도 이것은 '순차적' 사고가 맞지 않는 시대의 예입니다. 문제는 10개의 스레드를 만들고 실행하는 명령만 제공했다는 것입니다. 특수 운영 체제 메커니즘인 스레드 스케줄러가 실행 순서를 결정합니다. 정확한 디자인과 의사 결정 전략은 지금 당장 깊이 논의하지 않을 주제입니다. 기억해야 할 주요 사항은 프로그래머가 스레드의 실행 순서를 제어할 수 없다는 것입니다. 상황의 심각성을 이해하려면 위의 예에서 main() 메소드를 몇 번 더 실행해 보십시오. 두 번째 실행 시 콘솔 출력: 나는 스레드다! 제 이름은 Thread-0입니다. 저는 Thread입니다! 제 이름은 Thread-4입니다. 저는 Thread입니다! 제 이름은 Thread-3입니다. 저는 Thread입니다! 제 이름은 Thread-2입니다. 저는 Thread입니다! 제 이름은 Thread-1입니다. 저는 Thread입니다! 제 이름은 Thread-5입니다. 저는 Thread입니다! 제 이름은 Thread-6입니다. 저는 Thread입니다! 제 이름은 Thread-8입니다. 저는 Thread입니다! 제 이름은 Thread-9입니다. 저는 Thread입니다! 내 이름은 Thread-7 세 번째 실행의 콘솔 출력: I'm Thread! 제 이름은 Thread-0입니다. 저는 Thread입니다! 제 이름은 Thread-3입니다. 저는 Thread입니다! 제 이름은 Thread-1입니다. 저는 Thread입니다! 제 이름은 Thread-2입니다. 저는 Thread입니다! 제 이름은 Thread-6입니다. 저는 Thread입니다! 제 이름은 Thread-4입니다. 저는 Thread입니다! 제 이름은 Thread-9입니다. 저는 Thread입니다! 제 이름은 Thread-5입니다. 저는 Thread입니다! 제 이름은 Thread-7입니다. 저는 Thread입니다! 내 이름은 스레드-8입니다.

멀티스레딩으로 인한 문제

책에 대한 예에서 멀티스레딩이 매우 중요한 작업을 해결하고 프로그램을 더 빠르게 만들 수 있음을 확인했습니다. 종종 몇 배 더 빠릅니다. 그러나 멀티스레딩은 어려운 주제로 여겨진다. 실제로 부적절하게 사용하면 문제를 해결하는 대신 문제를 만듭니다. 내가 '문제를 일으킨다'고 말할 때 어떤 추상적인 의미가 아닙니다. 다중 스레딩이 생성할 수 있는 두 가지 특정 문제는 교착 상태와 경합 상태입니다. 교착 상태는 여러 스레드가 서로 보유하고 있는 리소스를 기다리고 있고 그 중 어느 것도 계속 실행할 수 없는 상황입니다. 다음 수업에서 더 자세히 이야기하겠습니다. 지금은 다음 예제로 충분합니다. Java의 멀티스레딩: 정의, 이점 및 일반적인 함정 - 4Thread-1이 일부 Object-1과 상호 작용하고 Thread-2가 Object-2와 상호 작용한다고 상상해 보십시오. 또한 프로그램은 다음과 같이 작성됩니다.
  1. Thread-1은 Object-1과의 상호 작용을 중지하고 Thread-2가 Object-2와의 상호 작용을 중단하고 Object-1로 전환되는 즉시 Object-2로 전환합니다.
  2. Thread-2는 Object-2와의 상호 작용을 중지하고 Thread-1이 Object-1과의 상호 작용을 중단하고 Object-2로 전환되는 즉시 Object-1로 전환합니다.
멀티스레딩에 대한 깊은 이해가 없어도 아무 일도 일어나지 않는다는 것을 쉽게 알 수 있습니다. 스레드는 위치를 바꾸지 않고 서로를 영원히 기다립니다. 오류는 명백해 보이지만 실제로는 그렇지 않습니다. 프로그램에서 쉽게 할 수 있습니다. 다음 단원에서 교착 상태를 유발하는 코드의 예를 살펴보겠습니다. 그건 그렇고, Quora는 교착 상태가 무엇인지 설명하는 훌륭한 실제 예를 가지고 있습니다.이다. '인도의 일부 주에서는 등록된 농부가 아니면 농지를 팔지 않습니다. 그러나 농지를 소유하지 않으면 농부로 등록하지 않습니다.' 엄청난! 우리는 무엇을 말할 수 있습니까?! :) 이제 경쟁 조건에 대해 이야기해 봅시다. 경쟁 조건은 멀티스레드 시스템 또는 응용 프로그램의 설계 오류로, 시스템 또는 응용 프로그램의 작동은 코드 부분이 실행되는 순서에 따라 달라집니다. 스레드를 시작한 예제를 기억하세요.

public class MyFirstThread extends Thread {

   @Override
   public void run() {
       System.out.println("Thread executed: " + getName());
   }
}

public class Main {

   public static void main(String[] args) {

       for (int i = 0; i < 10; i++) {

           MyFirstThread thread = new MyFirstThread();
           thread.start();
       }
   }
}
이제 프로그램이 음식을 요리하는 로봇을 실행하는 역할을 한다고 상상해 보십시오! Thread-0은 냉장고에서 계란을 꺼냅니다. Thread-1은 스토브를 켭니다. Thread-2는 팬을 가져와 스토브 위에 놓습니다. Thread-3가 스토브에 불을 붙입니다. Thread-4가 팬에 기름을 붓습니다. Thread-5는 계란을 깨서 팬에 붓습니다. Thread-6는 달걀 껍질을 쓰레기통에 버립니다. Thread-7은 버너에서 익힌 계란을 제거합니다. Thread-8은 익힌 계란을 접시에 담습니다. Thread-9가 설거지를 합니다. 프로그램의 결과를 보십시오: 실행된 스레드: 스레드-0 실행된 스레드: 스레드-2 실행된 스레드-1 실행된 스레드: 스레드-4 실행된 스레드: 스레드-9 실행된 스레드: 스레드-5 실행된 스레드: 스레드-8 스레드 실행됨: 스레드-7 실행된 스레드: 스레드-3 코미디 루틴인가요? :) 그리고 우리 프로그램의 작업은 스레드의 실행 순서에 따라 달라지기 때문입니다. 필요한 순서를 조금이라도 위반하면 우리 부엌은 지옥으로 변하고 미친 로봇이 주변의 모든 것을 파괴합니다. 이는 다중 스레드 프로그래밍에서 흔히 발생하는 문제이기도 합니다. 그것에 대해 한 번 이상 듣게 될 것입니다. 이 수업을 마치면서 멀티스레딩에 관한 책을 추천하고 싶습니다. Java의 멀티스레딩: 정의, 이점 및 일반적인 함정 - 6'Java Concurrency in Practice'는 2006년에 작성되었지만 관련성을 잃지 않았습니다. 기본부터 가장 일반적인 실수 및 반패턴에 이르기까지 다중 스레드 Java 프로그래밍 전용입니다. 언젠가 멀티스레딩 전문가가 되기로 결심했다면 이 책은 반드시 읽어야 할 책입니다. 다음 수업에서 만나요! :)
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION