まず、Javaのアプリケーションとプロセスに関連する概念的な知識について説明し、スレッドの作成方法とプロセスの作成方法を説明しましょう。この記事のディレクトリの概要は次のとおりです。
1. Javaのアプリケーションとプロセスに関連する概念
2。Javaでスレッドを作成する方法
3. Javaでプロセスを作成する方法
1. Javaのアプリケーションとプロセスに関連する概念
Javaでは、アプリケーションはJVMインスタンス(JVMプロセスとも呼ばれます)に対応し、名前はjava.exeまたはjavaw.exeにデフォルトです(Windowsの下のタスクマネージャーを通じて表示できます)。 Javaは、シングルスレッドプログラミングモデルを採用しています。つまり、独自のプログラムでスレッドを積極的に作成しない場合、通常はメインスレッドと呼ばれるスレッドのみを作成します。ただし、タスクを実行するスレッドは1つだけですが、JVMに1つのスレッドしかないことを意味しないことに注意してください。 JVMインスタンスを作成すると、他の多くのスレッドが作成されます(ガベージコレクタースレッドなど)。
JavaはSingreadedプログラミングモデルを採用しているため、UIをプログラミングするときは、メインスレッドのブロックを避けるために、子スレッドに時間のかかる操作を配置することに注意する必要があります(メインスレッドは、ユーザーインタラクションイベントを処理するために使用されるUIスレッドです)。
2。Javaでスレッドを作成する方法
Javaでスレッドを作成する場合、通常、2つの方法があります。1)スレッドクラスを継承します。 2)実行可能なインターフェイスを実装します。
1。スレッドクラスを継承します
スレッドクラスを継承する場合は、実行方法をオーバーライドし、実行方法で実行する必要があるタスクを定義する必要があります。
クラスMythreadはスレッドを拡張します{private static int num = 0; public mythread(){num ++; } @Override public void run(){system.out.println( "アクティブに作成された"+num+"スレッド"); }}独自のスレッドクラスを作成した後、スレッドオブジェクトを作成してから、start()メソッドを介してスレッドを開始できます。スレッドを起動するのはrun()メソッドとは呼ばれないことに注意してください。実行方法は、実行する必要があるタスクのみを定義します。実行メソッドが呼び出された場合、メインスレッドで実行メソッドを実行することと同等です。これは、通常のメソッド呼び出しと違いはありません。現時点では、定義されたタスクを実行するための新しいスレッドは作成されません。
public class test {public static void main(string [] args){mythread thread = new mythread(); thread.start(); }} class mythread extends thread {private static int num = 0; public mythread(){num ++; } @Override public void run(){system.out.println( "アクティブに作成された"+num+"スレッド"); }}上記のコードでは、start()メソッドを呼び出すことにより、新しいスレッドが作成されます。 start()メソッド呼び出しとrun()メソッド呼び出しの違いを区別するために、次の例を参照してください。
public class test {public static void main(string [] args){system.out.println( "main thread id:"+thread.currentthread()。getId()); mythread thread1 = new mythread( "thread1"); thread1.start(); mythread thread2 = new mythread( "thread2"); thread2.run(); }} class mythread extends thread {private string name; public mythread(string name){this.name = name; } @Override public void run(){system.out.println( "name:"+name+"子スレッドID:"+thread.currentthread()。getId()); }}実行結果:
出力の結果から、次の結論を描画できます。
1)thread1とthread2のスレッドIDは異なり、thread2とメインスレッドIDは同じです。つまり、実行メソッド呼び出しは新しいスレッドを作成しませんが、メインスレッドで実行方法を直接実行します。これは通常のメソッド呼び出しと違いはありません。
2)thread1の開始メソッド呼び出しはthread2の実行方法の前に呼び出されますが、thread2の実行メソッド呼び出しに関する情報は最初に出力され、新しいスレッドを作成するプロセスがメインスレッドの後続の実行をブロックしないことを示します。
2。実行可能なインターフェイスを実装します
スレッドクラスの継承に加えて、Javaでスレッドを作成することも、実行可能なインターフェイスを実装することにより、同様の関数を実装することもできます。実行可能なインターフェイスを実装するには、実行方法をオーバーライドする必要があります。
これが例です:
public class test {public static void main(string [] args){system.out.println( "main thread id:"+thread.currentthread()。getId()); myrunnable runnable = new myRunnable();スレッドスレッド= newスレッド(runnable); thread.start(); }} class myrunnable runnable {public myRunnable(){} @Override public void run(){System.out.println( "subthread id:"+thread.currentthread()。getId()); }}実行可能は、中国語で「タスク」を意味します。名前が示すように、実行可能なインターフェイスを実装することにより、サブタスクを定義し、サブタスクを渡してスレッドを実行して実行します。このメソッドは、スレッドクラスのパラメーターとしてrunnableを使用し、新しいスレッドを作成してスレッド開始メソッドを介してサブタスクを実行する必要があることに注意してください。実行可能な実行方法が呼び出された場合、新しいスレッドは作成されず、この通常のメソッド呼び出しに違いはありません。
実際、スレッドクラスの実装ソースコードを見ると、スレッドクラスが実行可能なインターフェイスを実装することがわかります。
Javaでは、これら2つの方法を使用して、サブタスクを実行するスレッドを作成できます。選択する特定の方法は、ニーズに依存します。スレッドクラスを直接継承する場合、実行可能なインターフェイスを実装するよりも簡潔に見える場合があります。ただし、Javaは単一の継承のみを許可するため、カスタムクラスが他のクラスを継承する必要がある場合、実行可能なインターフェイスを実装することのみを選択できます。
3. Javaでプロセスを作成する方法
Javaでは、プロセスを作成するには2つの方法があり、合計5つのメインクラスが含まれます。
最初の方法は、runtime.exec()メソッドを介してプロセスを作成することであり、2番目の方法は、プロセスビルダーの開始方法を介してプロセスを作成することです。これら2つの方法の違いとつながりについて話しましょう。
私が最初に話したいのは、プロセスクラスです。プロセスクラスは抽象クラスです。主にいくつかの抽象的なメソッドがあります。プロセスクラスのソースコードを見ることで、これを学ぶことができます。
java.lang.processパスにあります:
public class test {public static void main(string [] args){system.out.println( "main thread id:"+thread.currentthread()。getId()); myrunnable runnable = new myRunnable();スレッドスレッド= newスレッド(runnable); thread.start(); }} class myrunnable runnable {public myRunnable(){} @Override public void run(){System.out.println( "subthread id:"+thread.currentthread()。getId()); }}1)ProcessBuilderを介してプロセスを作成します
ProcessBuilderは、2つのコンストラクターを持つ最終クラスです。
public final class processbuilder {private list <string>コマンド;プライベートファイルディレクトリ。プライベートマップ<文字列、文字列>環境;プライベートブールリダイレクトエラーストリーム; public ProcessBuilder(List <String>コマンド){if(command == null)throw new nullpointerexception(); this.command = command; } public ProcessBuilder(string ... command){this.command = new ArrayList <String>(command.length); for(string arg:command)this.command.add(arg); } ......}コンストラクターは、作成する必要があるプロセスのコマンドパラメーターを渡します。最初のコンストラクターは、コマンドパラメーターをリストに入れ、無期限に長い文字列の形でそれらを渡します。
それでは、見下ろし続けましょう。前述のように、ProcessBuilderの開始方法を通じて新しいプロセスを作成します。開始方法で正確に行われていることを見てみましょう。以下は、開始方法の特定の実装ソースコードです。
public Process start()throws ioException {// Arrayを最初に変換する必要があります - 悪意のあるユーザーsupplied //リストはセキュリティチェックを回路にしようとする場合があります。虚偽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をスロー( "Ca n't Ca n't run program /" " + prog +" /"" +(dir == null? "": "(in directory /" " + dir +" /")") + ":" + e.getmessage()、e);}}}このメソッドはプロセスオブジェクトを返します。メソッドの最初の部分は、コマンドパラメーターとセットワーキングディレクトリに基づいていくつかのパラメーターを設定することと同等です。最も重要なことは、Tryステートメントブロックの文です。
return processimpl.start(cmdarray、環境、dir、redirecterrorStream);
これは、実際にプロセスを作成する文です。 ProcessIMPLクラスの開始方法が呼び出されることに注意してください。ここでは、開始が静的な方法でなければならないことがわかります。では、どのようなProcessImplですか?このクラスは、java.lang.processimplパスにもあります。このクラスの具体的な実装を見てみましょう。
ProcessImplは最終クラスでもあり、プロセスクラスを継承します。
最終クラスProcessImplはプロセスを拡張します{// ProcessBuilder.start()Static Process Start(String Cmdarray []、Java.util.map <String、String> Environment、String Dir、Boolean Redirecterrorstream)Throws IOException {string envblock = processenvirnmentblock(環境) new processimpl(cmdarray、envblock、dir、redirecterrorStream)を返します。 } ....}これは、ProcessImplクラスの開始方法の特定の実装です。実際、この文はProcessImplオブジェクトを作成するために使用されます。
new processimpl(cmdarray、envblock、dir、redirecterrorStream)を返します。
ProcessImplでは、プロセスクラスのいくつかの抽象的なメソッドが具体的な実装に実装されています。
実際、ProcessIMPLオブジェクトは、ProcessBuilderの開始方法を介して作成されます。
ProcessBuilderを使用してプロセスを作成する例を見てみましょう。たとえば、ProcessBuilderを介してプロセスを開始してCMDを開き、IPアドレス情報を取得したい場合は、次のように書くことができます。
public class test {public static void main(string [] args)throws ioexception {processbuilder pb = new processBuilder( "cmd"、 "/c"、 "ipconfig/all");プロセスプロセス= pb.start();スキャナースキャナー=新しいスキャナー(process.getInputStream()); while(scanner.hasnextline()){system.out.println(scanner.nextline()); } scanner.close(); }}最初のステップは最も重要なものです。これは、コマンド文字列をProcessBuilderコンストラクターに渡すことです。一般的に言えば、文字列内の各独立コマンドは別のパラメーターとして使用されますが、リストに順番に配置して渡すこともできます。
他の多くの特定の使用法については、プロセス環境変数の設定やProcessBuilderの環境方法とディレクトリ(ファイルディレクトリ)を介した作業ディレクトリなど、ここでは詳しく説明しません。興味のある友達は、関連するAPIドキュメントを表示できます。
2)RuntimeのExecメソッドを使用してプロセスを作成します
まず、ランタイムクラスとEXECメソッドの特定の実装を見てみましょう。ランタイムは、名前が示すように、ランニングを意味し、現在のプロセスがある仮想マシンインスタンスを表します。
任意のプロセスは1つの仮想マシンインスタンスでのみ実行されるため、シングルトンモードはランタイムで使用されます。つまり、1つの仮想マシンインスタンスのみが生成されます。
public class runtime {private static Runtime currentRuntime = new Runtime(); /***現在のJavaアプリケーションに関連付けられたランタイムオブジェクトを返します。 * class <code> runtime </code>のメソッドのほとんどはインスタンス *メソッドであり、現在のランタイムオブジェクトに関して呼び出す必要があります。 * * @return <code> runtime </code>現在の * javaアプリケーションに関連付けられています。 */ public static Runtime getRuntime(){return currentRuntime; } / **このクラスをインスタンス化させないでください* / privateRuntime(){} ...}ここから、ランタイムクラスのコンストラクターはプライベートであるため、GetRuntimeを通じてランタイムインスタンスのみを取得できることがわかります。次に、Exec Methodの実装を詳しく見てみましょう。実行時にはExecの複数の異なる過負荷実装がありますが、実行の終了はExecメソッドのこのバージョンです。
パブリックプロセスexec(String [] cmdarray、string [] envp、file dir)throws ioexception {return new processbuilder(cmdarray).environment(envp).directory(dir).start(); }実際、プロセスがランタイムクラスのexecを通じて作成された場合、最終的にはプロセスビルダークラスの開始方法を通じて作成されることがわかります。
ランタイムのexecを使用してプロセスを作成する方法を確認する例を見てみましょう。または、前の例では、CMDに電話してIPアドレス情報を取得します。
public class test {public static void main(string [] args)throws 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は無期限の長さのパラメーターをサポートしています)。したがって、コマンドパラメーターを最初に渡す前にスプレッチする必要があります。
当面の間、Javaでスレッドとプロセスを作成する方法についてお話します。興味のある友達は関連情報を参照できます。