먼저 Java의 응용 프로그램 및 프로세스와 관련된 개념적 지식에 대해 이야기 한 다음 스레드를 만드는 방법과 프로세스를 만드는 방법을 설명해 봅시다. 이 기사의 디렉토리 개요는 다음과 같습니다.
1. Java의 응용 프로그램 및 프로세스와 관련된 구성
2. 자바에서 스레드를 만드는 방법
3. Java에서 프로세스를 만드는 방법
1. Java의 응용 프로그램 및 프로세스와 관련된 구성
Java에서 응용 프로그램은 JVM 인스턴스 (JVM 프로세스라고도 함)에 해당하고 이름 기본값은 java.exe 또는 javaw.exe로 기본값을 제공합니다 (Windows의 작업 관리자를 통해 볼 수 있음). Java는 단일 스레드 프로그래밍 모델을 채택합니다. 즉, 자체 프로그램에서 스레드를 적극적으로 생성하지 않으면 일반적으로 주 스레드라고하는 하나의 스레드 만 생성합니다. 그러나 작업을 수행 할 스레드가 하나만 있다고해서 JVM에 스레드가 하나만 있다는 것을 의미하지는 않습니다. JVM 인스턴스를 생성 할 때는 다른 스레드가 생성됩니다 (예 : 쓰레기 수집기 스레드).
Java는 단일 스레드 프로그래밍 모델을 채택하기 때문에 UI를 프로그래밍 할 때는 메인 스레드를 차단하지 않도록 어린이 스레드에 시간이 많이 걸리는 작업을 하위 스레드에 넣는 데주의를 기울여야합니다 (UI를 프로그래밍 할 때 메인 스레드는 UI 스레드이며 사용자 상호 작용 이벤트를 처리하는 데 사용됩니다).
2. 자바에서 스레드를 만드는 방법
Java에서 스레드를 만들려면 일반적으로 두 가지 방법이 있습니다. 1) 스레드 클래스를 상속받습니다. 2) 실행 가능한 인터페이스를 구현하십시오.
1. 스레드 클래스를 상속합니다
스레드 클래스를 상속하면 실행 메소드를 무시하고 실행 메소드에서 실행 해야하는 작업을 정의해야합니다.
클래스 Mythread는 스레드 {private static int num = 0; public mythread () {num ++; } @override public void run () {System.out.println ( "Actively 작성"+num+"스레드"); }}나만의 스레드 클래스를 작성한 후에는 스레드 객체를 작성한 다음 start () 메소드를 통해 스레드를 시작할 수 있습니다. 스레드를 시작하기 위해 run () 메소드라고 부르지 않습니다. 실행 메소드는 실행 해야하는 작업 만 정의합니다. 실행 메소드가 호출되면 기본 스레드에서 실행 메소드를 실행하는 것과 같습니다. 이는 일반 메소드 호출과 다르지 않습니다. 현재 정의 된 작업을 실행하기 위해 새 스레드가 생성되지 않습니다.
공개 클래스 테스트 {public static void main (String [] args) {Mythread Thread = new Mythread (); thread.start (); }} class mythread는 스레드 {private static int num = 0; public mythread () {num ++; } @override public void run () {System.out.println ( "Actively 작성"+num+"스레드"); }}위 코드에서는 start () 메소드를 호출하여 새 스레드가 생성됩니다. start () 메소드 호출 및 run () 메소드 호출의 차이를 구별하려면 다음 예를 참조하십시오.
공개 클래스 테스트 {public static void main (String [] args) {System.out.println ( "메인 스레드 ID :"+thread.currentThread (). getId ()); Mythread Thread1 = New Mythread ( "Thread1"); thread1.start (); Mythread Thread2 = New Mythread ( "Thread2"); Thread2.run (); }} class mythread는 스레드 {private String name; public mythread (문자열 이름) {this.name = name; } @override public void run () {system.out.println ( "name :"+name+"child 스레드 ID :"+thread.currentThread (). getId ()); }}실행 결과 :
출력 결과에서 다음과 같은 결론을 도출 할 수 있습니다.
1) Thread1 및 Thread2의 스레드 ID는 다르고 Thread2와 기본 스레드 ID는 동일합니다. 즉, 실행 메소드 호출이 새 스레드를 생성하지 않지만 기본 스레드에서 실행 메소드를 직접 실행하여 일반 메소드 호출과 다릅니다.
2) Thread2의 실행 메소드 전에 STREW의 시작 방법 호출이 호출되지만 Thread2의 실행 메소드 호출에 대한 정보가 먼저 출력되므로 새 스레드를 생성하는 프로세스가 기본 스레드의 후속 실행을 차단하지 않을 것입니다.
2. 런닝 가능한 인터페이스를 구현하십시오
스레드 클래스를 상속하는 것 외에도 Java에서 스레드를 작성하면 런닝 가능한 인터페이스를 구현하여 유사한 기능을 구현할 수 있습니다. 실행 가능한 인터페이스를 구현하면 실행 메소드를 대체해야합니다.
예는 다음과 같습니다.
공개 클래스 테스트 {public static void main (String [] args) {System.out.println ( "메인 스레드 ID :"+thread.currentThread (). getId ()); Myrunnable Runnable = New Myrunnable (); 스레드 스레드 = 새 스레드 (runnable); thread.start (); }} class myrunnable emplements runnable {public myrunnable () {} @override public void run () {system.out.println ( "하위 스레드 ID :"+thread.currentThread (). getId ()); }}실행 가능한 것은 중국어로 "작업"을 의미합니다. 이름에서 알 수 있듯이 런닝 가능한 인터페이스를 구현함으로써 하위 작업을 정의한 다음 하위 태스크를 뿌려 실행할 스레드를 넘겨줍니다. 이 메소드는 실행 가능한 스레드 클래스의 매개 변수로 런 가능한 사용을 사용한 다음 스레드 시작 메소드를 통해 하위 작업을 실행하기 위해 새 스레드를 작성해야합니다. 실행 가능한 실행 방법이 호출되면 새 스레드가 생성되지 않으며이 일반 메소드 호출에는 차이가 없습니다.
실제로 스레드 클래스의 구현 소스 코드를 보면 스레드 클래스가 런닝 가능한 인터페이스를 구현한다는 것을 알게됩니다.
Java에서는이 두 가지 방법을 사용하여 하위 작업을 실행하는 스레드를 작성할 수 있습니다. 선택할 수있는 특정 방법은 귀하의 요구에 따라 다릅니다. 스레드 클래스를 직접 상속하면 런닝 가능한 인터페이스를 구현하는 것보다 더 간결하게 보일 수 있습니다. 그러나 Java는 단일 상속 만 허용하므로 사용자 정의 클래스가 다른 클래스를 상속 해야하는 경우 런닝 가능한 인터페이스 만 구현하도록 선택할 수 있습니다.
3. Java에서 프로세스를 만드는 방법
Java에는 총 5 개의 주요 클래스가 포함 된 프로세스를 만드는 두 가지 방법이 있습니다.
첫 번째 방법은 runtime.exec () 메소드를 통해 프로세스를 작성하는 것이며, 두 번째 방법은 ProcessBuilder의 시작 방법을 통해 프로세스를 작성하는 것입니다. 이 두 방법의 차이점과 연결에 대해 이야기 해 봅시다.
내가 말하고 싶은 첫 번째 것은 프로세스 클래스입니다. 프로세스 클래스는 추상 클래스입니다. 주로 몇 가지 추상 방법이 있습니다. 프로세스 클래스의 소스 코드를 살펴보면이를 배울 수 있습니다.
Java.lang.process 경로에 위치 :
공개 클래스 테스트 {public static void main (String [] args) {System.out.println ( "메인 스레드 ID :"+thread.currentThread (). getId ()); Myrunnable Runnable = New Myrunnable (); 스레드 스레드 = 새 스레드 (runnable); thread.start (); }} class myrunnable emplements runnable {public myrunnable () {} @override public void run () {system.out.println ( "하위 스레드 ID :"+thread.currentThread (). getId ()); }}1) ProcessBuilder를 통해 프로세스를 만듭니다
ProcessBuilder는 두 명의 생성자가있는 최종 클래스입니다.
공개 최종 클래스 ProcessBuilder {private list <string> 명령; 개인 파일 디렉토리; 개인지도 <문자열, 문자열> 환경; 전용 부울 리디렉터링; public processBuilder (list <string> command) {if (command == null) 던지기 nullpointerexception (); this.command = 명령; } public processBuilder (문자열 ... 명령) {this.command = new ArrayList <string> (명령 .length); for (string arg : command) this.command.add (arg); } ......}생성자는 생성 해야하는 프로세스의 명령 매개 변수를 전달합니다. 첫 번째 생성자는 명령 매개 변수를 목록에 넣고 무기한 긴 문자열의 형태로 전달합니다.
계속 내려다 보자. 앞에서 언급했듯이 ProcessBuilder의 시작 방법을 통해 새로운 프로세스를 만듭니다. 시작 방법에서 정확히 무엇이 수행되는지 살펴 보겠습니다. 다음은 시작 방법의 특정 구현 소스 코드입니다.
public process start ()는 ioexception {// array로 변환해야합니다-악의적 인 사용자-공급 // 목록은 보안 확인 [] cmdarray = command.toArray (new String [command.size ()); for (arg == null) trown indelycection (); // whorlpoincection (); // emptystring prog = cmdarray [0]; SecurityManager Security = System.GetSecurityManager (); if (Security! = null) Security.CheckExec (Prog); 문자열 dir = directory == null? null : directory.toString (); try {return processimpl.start (cmdarray, 환경, dir, redirecterrorstream);} catch (ioexception e) {// 문제를 발견 한 낮은 수준 C 코드보다 고품질 오류 // 메시지를 만들기가 훨씬 쉽습니다. 새 IoException ( ""프로그램 /"" + prog + " /" "" + (dir == null? "이 메소드는 프로세스 객체를 반환합니다. 이 메소드의 첫 번째 부분은 명령 매개 변수 및 세트 작업 디렉토리를 기반으로 일부 매개 변수를 설정하는 것과 같습니다. 가장 중요한 것은 Try Statement 블록의 문장입니다.
Return ProcessImpl.start (cmdarray, Environment, Dir, redirecterrorstream);
이것은 실제로 프로세스를 만드는 문장입니다. ProcessImpl 클래스의 시작 방법이 호출됩니다. 여기서 우리는 시작이 정적 방법이어야한다는 것을 알 수 있습니다. 그렇다면 어떤 종류의 ProcessImpl입니까? 이 클래스는 Java.lang.processimpl 경로에도 있습니다. 이 클래스의 구현을 살펴 보겠습니다.
ProcessImpl은 또한 프로세스 클래스를 상속하는 최종 클래스입니다.
최종 클래스 ProcessImpl은 프로세스를 확장합니다. {// processBuilder.start () 정적 프로세스 시작 (String cmdarray [], java.util.map <string, string> 환경, 문자열 dir, boolean redirecterrorstream)의 systate epoctor.static process start (string cmdarray [], java.util.map <string, string> 환경, boolean redirecterrorstream)는 ioexception {string envblock = processenventment.toenvernmentment.toenvonblock (환경); 새로운 processimpl을 반환합니다 (cmdarray, envblock, dir, redirecterrorstream); } ....}이것은 ProcessIMPL 클래스의 시작 방법의 특정 구현입니다. 실제로이 문장은 ProcessIMPL 객체를 만드는 데 사용됩니다.
새로운 processimpl을 반환합니다 (cmdarray, envblock, dir, redirecterrorstream);
ProcessImpl에서는 프로세스 클래스의 몇 가지 추상 방법이 구체적인 구현에서 구현됩니다.
실제로, ProcessIMPL 객체는 ProcessBuilder의 시작 방법을 통해 생성됩니다.
ProcessBuilder를 사용하여 프로세스를 작성하는 예를 살펴 보겠습니다. 예를 들어, ProcessBuilder를 통해 프로세스를 시작하여 CMD를 열고 IP 주소 정보를 얻으려면 다음과 같이 쓸 수 있습니다.
public class test {public static void main (String [] args)은 ioexception {processBuilder pb = new ProcessBuilder ( "CMD", "/C", "ipConfig/All"); 프로세스 프로세스 = pb.start (); 스캐너 스캐너 = 새 스캐너 (process.getInputStream ()); while (scanner.hasnextline ()) {system.out.println (scanner.nextline ()); } scanner.close (); }}첫 번째 단계는 가장 중요하며, 이는 명령 문자열을 ProcessBuilder 생성자에게 전달하는 것입니다. 일반적으로 문자열의 각각의 독립 명령은 별도의 매개 변수로 사용되지만 순서대로 목록에 배치하고 통과 할 수도 있습니다.
프로세스 빌더의 환경 메소드 및 디렉토리 (파일 디렉토리)를 통한 프로세스 환경 변수 및 작업 디렉토리 등과 같이 다른 많은 특정 사용법에 대해서는 여기에서 자세히 설명하지 않습니다. 관심있는 친구는 관련 API 문서를 볼 수 있습니다.
2) 런타임의 실행 방법을 통해 프로세스를 만듭니다
먼저, 런타임 클래스 및 exec 방법의 특정 구현을 살펴 보겠습니다. 이름에서 알 수 있듯이 런타임은 실행을 의미하며 현재 프로세스가 위치한 가상 머신 인스턴스를 나타냅니다.
모든 프로세스는 하나의 가상 머신 인스턴스에서만 실행되므로 싱글 톤 모드는 런타임에 사용되므로 하나의 가상 머신 인스턴스 만 생성됩니다.
공개 클래스 런타임 {private static 런타임 currentRuntime = new Runtime (); /*** 현재 Java 응용 프로그램과 관련된 런타임 개체를 반환합니다. * 클래스 <code> 런타임의 대부분의 방법 </code>는 인스턴스 * 메소드이며 현재 런타임 개체와 관련하여 호출해야합니다. * * @return <code> runtime </code> 현재 * Java 응용 프로그램과 관련된 오브젝트. */ public static runtime getRuntime () {return currentRuntime; } / ** 다른 사람 이이 클래스를 인스턴스화하게하지 마십시오* / private runtime () {} ...}여기에서 런타임 클래스의 생성자가 비공개이므로 getRuntime을 통해 런타임 인스턴스 만 얻을 수 있음을 알 수 있습니다. 다음으로 EXEC 메소드 구현을 자세히 살펴 보겠습니다. 런타임에는 EXEC의 여러 가지 과부하 구현이 있지만 실행 종료는이 버전의 EXEC 메소드입니다.
public process exec (string [] cmdarray, string [] envp, file dir)은 ioexception {return new ProcessBuilder (cmdarray) .environment (ENVP) .Directory (dir) .start (); }실제로 런타임 클래스의 실행을 통해 프로세스가 생성되면 궁극적으로 ProcessBuilder 클래스의 시작 방법을 통해 생성됩니다.
Runtime의 Exec 또는 이전 예제를 통해 프로세스를 작성하는 방법을 확인하려면 예제를 살펴 보겠습니다. CMD에 전화하여 IP 주소 정보를 얻으십시오.
공개 클래스 테스트 {public static void main (String [] args)은 ioexception {string cmd = "cmd"+"/c"+"ipconfig/all"; 프로세스 프로세스 = runtime.getRuntime (). exec (cmd); 스캐너 스캐너 = 새 스캐너 (process.getInputStream ()); while (scanner.hasnextline ()) {system.out.println (scanner.nextline ()); } scanner.close (); }}EXEC 방법은 무한 길이 매개 변수를 지원하지 않으므로 (ProcessBuilder는 무한 길이 매개 변수를 지원 함), 전달하기 전에 명령 매개 변수를 먼저 스 플라이싱해야합니다.
당분간 자바에서 스레드와 프로세스를 만드는 방법에 대해 이야기하겠습니다. 관심있는 친구는 관련 정보를 참조 할 수 있습니다.