멀티스레딩으로 해결되는 문제
멀티스레딩은 실제로 두 가지 중요한 목표를 달성하기 위해 발명되었습니다.-
동시에 여러 가지 작업을 수행합니다.
위의 예에서 서로 다른 스레드(가족 구성원)는 여러 작업을 병렬로 수행했습니다. 설거지, 가게에 가기, 물건 포장하기 등이 있습니다.
프로그래밍과 더 밀접하게 관련된 예를 제공할 수 있습니다. 사용자 인터페이스가 있는 프로그램이 있다고 가정합니다. 프로그램에서 '계속'을 클릭하면 일부 계산이 수행되고 사용자는 다음 화면을 보게 됩니다. 이러한 작업이 순차적으로 수행되면 사용자가 '계속' 버튼을 클릭한 후 프로그램이 중단됩니다. 사용자는 프로그램이 모든 내부 계산을 수행하고 사용자 인터페이스가 새로 고쳐지는 부분에 도달할 때까지 '계속' 버튼 화면이 있는 화면을 보게 됩니다.
글쎄, 우리는 몇 분 기다릴 것 같아요!
또는 프로그램을 재작업하거나 프로그래머가 말하는 것처럼 '병렬화'할 수 있습니다. 한 스레드에서 계산을 수행하고 다른 스레드에서 사용자 인터페이스를 그려봅시다. 대부분의 컴퓨터에는 이 작업을 수행할 수 있는 충분한 리소스가 있습니다. 이 경로를 택하면 프로그램이 중단되지 않고 사용자가 내부에서 일어나는 일에 대해 걱정하지 않고 화면 사이를 원활하게 이동할 수 있습니다. 하나는 다른 하나를 방해하지 않습니다 :)
-
더 빠르게 계산을 수행합니다.
여기서 모든 것이 훨씬 간단합니다. 프로세서에 여러 개의 코어가 있고 오늘날 대부분의 프로세서에 있는 경우 여러 코어가 작업 목록을 병렬로 처리할 수 있습니다. 분명히 우리가 1000개의 작업을 수행해야 하고 각각 1초가 걸린다면 하나의 코어는 1000초 안에, 두 개의 코어는 500초 안에, 세 개의 코어는 333초보다 약간 더 많은 시간에 목록을 완료할 수 있습니다.
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입니다.
멀티스레딩으로 인한 문제
책에 대한 예에서 멀티스레딩이 매우 중요한 작업을 해결하고 프로그램을 더 빠르게 만들 수 있음을 확인했습니다. 종종 몇 배 더 빠릅니다. 그러나 멀티스레딩은 어려운 주제로 여겨진다. 실제로 부적절하게 사용하면 문제를 해결하는 대신 문제를 만듭니다. 내가 '문제를 일으킨다'고 말할 때 어떤 추상적인 의미가 아닙니다. 다중 스레딩이 생성할 수 있는 두 가지 특정 문제는 교착 상태와 경합 상태입니다. 교착 상태는 여러 스레드가 서로 보유하고 있는 리소스를 기다리고 있고 그 중 어느 것도 계속 실행할 수 없는 상황입니다. 다음 수업에서 더 자세히 이야기하겠습니다. 지금은 다음 예제로 충분합니다.
- Thread-1은 Object-1과의 상호 작용을 중지하고 Thread-2가 Object-2와의 상호 작용을 중단하고 Object-1로 전환되는 즉시 Object-2로 전환합니다.
- Thread-2는 Object-2와의 상호 작용을 중지하고 Thread-1이 Object-1과의 상호 작용을 중단하고 Object-2로 전환되는 즉시 Object-1로 전환합니다.
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 코미디 루틴인가요? :) 그리고 우리 프로그램의 작업은 스레드의 실행 순서에 따라 달라지기 때문입니다. 필요한 순서를 조금이라도 위반하면 우리 부엌은 지옥으로 변하고 미친 로봇이 주변의 모든 것을 파괴합니다. 이는 다중 스레드 프로그래밍에서 흔히 발생하는 문제이기도 합니다. 그것에 대해 한 번 이상 듣게 될 것입니다. 이 수업을 마치면서 멀티스레딩에 관한 책을 추천하고 싶습니다. 
GO TO FULL VERSION