JavaRush /Java Blog /Random-KO /스트림으로 시간을 소중히 여기세요
Andrei
레벨 2

스트림으로 시간을 소중히 여기세요

Random-KO 그룹에 게시되었습니다

머리말. 페트야 삼촌

자, 우리가 물 한 병을 채우고 싶다고 가정해 봅시다. Petya 삼촌의 생수 한 병과 수도꼭지를 이용하실 수 있습니다. Petya 삼촌은 오늘 새 수도꼭지를 설치했고 그 아름다움을 계속 칭찬했습니다. 그 전에는 낡고 막힌 수도꼭지만 사용했기 때문에 병입 라인이 엄청났습니다. 조금 더듬으니 흘린 방향에서 물 채우는 소리가 들리고, 2분 뒤에도 병은 여전히 ​​채우는 단계에 있고, 평소 줄이 우리 뒤로 모여들고, 머리 속에는 삼촌이 얼마나 배려심이 깊은 이미지가 떠오른다. Petya는 최고의 H2O 분자만을 병에 담습니다. 삶의 훈련을받은 Petya 삼촌은 특히 공격적인 사람들을 진정시키고 가능한 한 빨리 끝내겠다고 약속합니다. 병을 마친 후 그는 다음 병을 가져다가 일반적인 압력을 가하는데, 이는 새 탭의 모든 기능을 드러내지 않습니다. 사람들이 행복하지 않네요... 스트림으로 시간 감상하기 - 1

이론

멀티스레딩은 단일 프로세스 내에서 여러 스레드를 생성하는 플랫폼의 기능입니다. 스레드를 생성하고 실행하는 것은 프로세스를 생성하는 것보다 훨씬 간단하므로 하나의 프로그램에서 여러 병렬 작업을 구현해야 하는 경우 추가 스레드가 사용됩니다. JVM에서는 모든 프로그램이 메인 스레드에서 실행되고 나머지는 메인 스레드에서 시작됩니다. 동일한 프로세스 내에서 스레드는 서로 데이터를 교환할 수 있습니다. 새 스레드를 시작할 때 메소드를 사용하여 이를 사용자 스레드로 선언할 수 있습니다.
setDaemon(true);
이러한 스레드는 실행 중인 다른 스레드가 남아 있지 않으면 자동으로 종료됩니다. 스레드에는 작업 우선순위가 있습니다. 우선순위를 선택한다고 해서 우선순위가 가장 높은 스레드가 우선순위가 낮은 스레드보다 빨리 완료된다는 보장은 없습니다.
  • MIN_PRIORITY
  • NORM_PRIORITY(기본값)
  • MAX_PRIORITY
스트림 작업 시 기본 방법:
  • run()– 스레드를 실행합니다.
  • start()– 스레드를 시작합니다
  • getName()– 스레드 이름을 반환합니다.
  • setName()– 스트림의 이름을 지정합니다.
  • wait()notify()– 상속된 메서드, 스레드는 다른 스레드에서 메서드가 호출될 때까지 기다립니다.
  • notify()– 상속된 메서드, 이전에 중지된 스레드를 다시 시작합니다.
  • notifyAll()– 상속된 메서드, 이전에 중지된 스레드를 다시 시작합니다.
  • sleep()– 지정된 시간 동안 스트림을 일시 중지합니다.
  • join()– 스레드가 완료될 때까지 기다립니다.
  • interrupt()– 스레드 실행을 중단합니다.
여기에서 더 많은 방법을 찾을 수 있습니다 . 프로그램에 다음이 있는 경우 새 스레드에 대해 생각해 볼 때입니다.
  • 네트워크 접속
  • 파일 시스템 액세스
  • GUI

스레드 클래스

Java의 스레드는 클래스 Thread와 그 하위 항목으로 표시됩니다. 아래 예제는 스트림 클래스의 간단한 구현입니다.
import static java.lang.System.out;

public class ExampleThread extends Thread{

    public static void main(String[] args) {
        out.println("Основной поток");
        new ExampleThread().start();
    }

    @Override
    public void run() {
        out.println("Новый поток");
    }
}
결과적으로 우리는
Основной поток
Новый поток
여기서는 클래스를 생성하고 클래스의 자손으로 만든 Thread다음, 메인 스레드를 시작하고 run()클래스 메서드를 재정의하는 main() 메서드를 작성합니다 Thread. 이제 클래스의 인스턴스를 생성하고 상속된 메서드를 실행한 후 start()메서드 본문에 설명된 모든 내용이 실행될 새 스레드를 시작합니다 run(). 복잡해 보이지만 예제 코드를 보면 모든 것이 명확해집니다.

실행 가능한 인터페이스

Oracle은 또한 새로운 스레드를 시작하기 위한 인터페이스 구현을 제안합니다 Runnable. 이는 이전 예제에서 유일하게 사용 가능한 상속보다 더 많은 설계 유연성을 제공합니다(클래스 소스를 보면 Thread인터페이스도 구현한다는 것을 알 수 있습니다 Runnable). 새 스레드를 생성할 때 권장되는 방법을 사용해 보겠습니다.
import static java.lang.System.out;

public class ExampleRunnable implements Runnable {

    public static void main(String[] args) {
        out.println("Основной поток");
        new Thread(new ExampleRunnable()).start();
    }

    @Override
    public void run() {
        out.println("Новый поток");
    }
}
결과적으로 우리는
Основной поток
Новый поток
예제가 매우 유사하기 때문에 run()코드를 작성할 때 인터페이스에 설명된 추상 메서드를 구현해야 했습니다 Runnable. 새로운 스레드를 시작하는 것은 약간 다릅니다. Thread인터페이스 구현 인스턴스에 대한 참조를 매개변수로 전달하여 클래스의 인스턴스를 만들었습니다 Runnable. 클래스를 직접 상속하지 않고도 새 스레드를 생성할 수 있는 것이 바로 이 접근 방식입니다 Thread.

긴 작업

다음 예에서는 다중 스레드 사용의 이점을 명확하게 보여줍니다. 몇 가지 긴 계산이 필요한 간단한 작업이 있다고 가정해 보겠습니다. 이 기사에 앞서 우리는 이를 메서드로 해결했을 것입니다. main()아마도 인식하기 쉽도록 별도의 메서드로 분류하거나 클래스로 나눌 수도 있지만 본질은 동일할 것입니다. 모든 작업은 순차적으로 수행됩니다. 중량 계산을 시뮬레이션하고 실행 시간을 측정해 보겠습니다.
public class ComputeClass {

    public static void main(String[] args) {
        // Узнаем стартовое время программы
        long startTime = System.currentTimeMillis();

        // Определяем долгосрочные операции
        for(double i = 0; i < 999999999; i++){
        }
        System.out.println("complete 1");
        for(double i = 0; i < 999999999; i++){
        }
        System.out.println("complete 2");
        for(double i = 0; i < 999999999; i++){
        }
        System.out.println("complete 3");

        //Вычисляем и выводим время выполнения программы
        long timeSpent = System.currentTimeMillis() - startTime;
        System.out.println("программа выполнялась " + timeSpent + " миллисекунд");
    }
}
결과적으로 우리는
complete 1
complete 2
complete 3
программа выполнялась 9885 миллисекунд
실행 시간은 많이 부족하며 이번에는 빈 출력 화면을보고 있으며 상황은 Petya 삼촌에 대한 이야기와 매우 유사합니다. 지금은 그의 역할에서 우리 개발자가 활용하지 않았습니다. 최신 장치의 모든 기능. 개선해드리겠습니다.
public class ComputeClass {

    public static void main(String[] args) {
        // Узнаем стартовое время программы
        long startTime = System.currentTimeMillis();

        // Определяем долгосрочные операции
        new MyThread(1).start();
        new MyThread(2).start();
        for(double i = 0; i < 999999999; i++){
        }
        System.out.println("complete 3");

        //Вычисляем и выводим время выполнения программы
        long timeSpent = System.currentTimeMillis() - startTime;
        System.out.println("программа выполнялась " + timeSpent + " миллисекунд");
    }
}

class MyThread extends Thread{
int n;

MyThread(int n){
    this.n = n;
}

    @Override
    public void run() {
        for(double i = 0; i < 999999999; i++){
        }
        System.out.println("complete " + n);
    }
}
결과적으로 우리는
complete 1
complete 2
complete 3
программа выполнялась 3466 миллисекунд
실행 시간이 크게 단축되었습니다(이 효과는 멀티스레딩을 지원하지 않는 프로세서에서는 달성되지 않거나 실행 시간이 늘어날 수도 있음). 스레드가 순서대로 종료될 수 있다는 점은 주목할 가치가 있으며 개발자가 작업의 예측 가능성이 필요한 경우 특정 사례에 대해 독립적으로 구현해야 합니다.

스레드 그룹

Java의 스레드는 그룹으로 결합될 수 있으며 클래스는 이를 위해 사용됩니다 ThreadGroup. 그룹에는 단일 스레드와 전체 그룹이 모두 포함될 수 있습니다. 이는 연결이 끊어졌을 때 네트워크와 관련된 흐름을 중단해야 하는 경우 편리할 수 있습니다. 여기에서 그룹에 대한 자세한 내용을 읽을 수 있습니다. 이제 주제가 더 명확해지고 사용자가 만족할 수 있기를 바랍니다.
스트림으로 시간 감상하기 - 2
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION