多くのコアJavaインタビューの質問は、マルチスレッドとコレクションのフレームワークから来ています。コアスレッドの概念を理解するときは、熟練した実務経験が必要です。この記事では、Javaスレッドに関する典型的な質問をいくつか収集します。これは、上級エンジニアからしばしば尋ねられます。
0。Javaのマルチスレッド同期とは何ですか?
マルチスレッドプログラムでは、同期は共有リソースへのアクセスを制御できます。同期がない場合、Javaスレッドが共有変数を変更している場合、別のスレッドが同じ変数を使用または更新しているため、プログラムで誤った結果につながる可能性があります。
1.マルチスレッドを実装するいくつかの方法を説明しますか?
Javaスレッドは、実行可能なインターフェイスを実装するか、スレッドクラスを継承して実装できます。複数回継承する場合は、Runnableを実装することを好みます。
2。thread.start()とthread.run()の違いは何ですか?
thread.start()メソッド(ネイティブ)がスレッドを起動し、準備ができた状態に入ります。 CPUがスレッドに時間を割り当てると、JVMはrun()メソッドを実行するようにスケジュールします。
3.なぜrun()とstart()メソッドが必要なのですか? run()メソッドを使用してタスクを完了できますか?
JVMは通常の方法の呼び出しとは異なる別のスレッドを作成するため、run()とstart()の2つの方法が必要です。したがって、この作業はスレッドの開始方法によって行われます。 STARTはローカルメソッドによって実装されており、表示可能に呼び出す必要があります。これら2つの方法を使用するもう1つの利点は、すべてのオブジェクトをスレッドとして実行できることです。実行可能なインターフェイスが実装されている限り、これにより、スレッドクラスを継承することによって引き起こされるJavaの複数の相続問題が回避されます。
4. Threadlocalクラスは何ですか?それを使用する方法は何ですか?
ThreadLocalは、「ローカルスレッド」ではなく、スレッドレベルのローカル変数です。 ThreadLocalは、変数を使用する各スレッドの変数の独立したコピーを提供します。各スレッドは、コピーを変更するときに他のスレッドオブジェクトのコピーに影響しません(翻訳者のメモ)。
ローカル変数のスレッドの重要なポイントは次のとおりです。
スレッドローカル変数(threadlocal変数)は、各スレッドに個別の変数を便利に提供します。
通常、Threadlocalインスタンスは、クラスにStartic(private static)フィールドとして表示されます。これは、スレッドの関連付けに使用されます。
複数のスレッドがthreadlocalインスタンスにアクセスすると、各スレッドは、threadlocalが提供する変数の独立したコピーを維持します。
一般的に使用される使用は、DAOモードで見ることができます。 DAOクラスがSingletonクラスの場合、データベース接続は各スレッドによって独立して維持され、互いに影響を与えません。 (スレッドに基づくシングルトン)
5. InvalidMonitorStateExceptionはいつスローされますか?その理由は何ですか?
wait()/notify()/notifyall()のメソッドを呼び出すと、現在のスレッドがオブジェクトのロックを取得しない場合、IllegalMonitorStateExceptionの例外がスローされます(つまり、プログラムがオブジェクトの同期ブロックまたは同期方法を実行しない場合、wait()/notify()/notify()/notify()を呼び出します。例外はruntimeexcpetionのサブクラスであるため、例外をキャッチする必要はありません(ただし、必要に応じてキャッチできます)。 runtimeexceptionとして、そのような例外は、wait()、notify()、notifyall()メソッドの署名では言及されていません。
6. sleep()、suspend()、wait()の違いは何ですか?
thread.sleep()は、指定された時間に「実行できない」状態で現在のスレッドを作成します。スレッドは常にオブジェクトのモニターを保持します。たとえば、スレッドが現在同期ブロックまたは同期方法にある場合、他のスレッドはブロックまたはメソッドに入ることができません。別のスレッドが割り込み()メソッドを呼び出すと、その「睡眠」スレッドが目覚めます。
注:Sleep()は静的な方法です。これは、現在のスレッドに対してのみ有効であり、一般的なエラーがT.Sleep()を呼び出すことを意味します(ここでは、Tは現在のスレッドとは異なるスレッドです)。 T.Sleep()が実行されたとしても、現在のスレッドはTスレッドではなく眠ります。 t.suspend()は時代遅れの方法です。 suspend()を使用すると、スレッドが停滞状態に入ります。スレッドは常にオブジェクトのモニターを保持し、suspend()はデッドロックの問題を引き起こす可能性があります。
object.wait()現在のスレッドを「払いのない」状態から出します。 Sleep()とは異なり、待機はスレッドではなくオブジェクトメソッドです。 Object.Wait()を呼び出すとき、スレッドは最初にこのオブジェクトのオブジェクトロックを取得する必要があります。現在のスレッドは、ロックオブジェクトを同期させ、現在のスレッドを待機キューに追加する必要があります。次に、別のスレッドが同じオブジェクトロックを同期してobject.notify()を呼び出すことができます。基本的にwait()/notify()はsleep()/arturn()に似ていますが、前者がオブジェクトロックを取得する必要があることを除きます。
7.静的メソッドで同期を使用するとどうなりますか?
静的メソッドを同期する場合、クラスの「クラス」オブジェクトが取得されます。したがって、スレッドが同期された静的メソッドに入ると、スレッドモニターはクラス自体のオブジェクトロックを取得し、他のスレッドはこのクラスの静的同期メソッドを入力できません。複数のスレッドが異なるインスタンスに同時にインスタンスメソッドに同時にアクセスできるため、インスタンスメソッドのようなものではありません。
8.同期メソッドが実行されたとき、スレッドはオブジェクトの非同期インスタンスメソッドを呼び出すことができますか?
はい、非同期方法はいつでも問題なく呼び出すことができます。実際、Javaは非同期方法のチェックを行わず、ロックオブジェクトは同期方法または同期コードブロックでのみチェックされます。メソッドが同期として宣言されていない場合、共有データを使用している場合でも、Javaは安全であるかどうかを確認せずに呼び出すので、この場合は特に注意してください。メソッドが同期されるかどうかは、重要なセクションアクセスによって異なります。メソッドが重要なセクション(共有リソースまたはデータ構造)にアクセスしない場合、同期を宣言する必要はありません。
例は次のとおりです。Commonクラスには2つのメソッドがsynchronizedmethod1()とmethod1()があり、Mythreadクラスはこれら2つのメソッドを独立したスレッドで呼び出します。
public class common {public synchronized void synchronizedmethod1(){system.out.println( "synchronizedmethod1 calk"); try {thread.sleep(1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "synchronizedmethod1 done"); } public void method1(){system.out.println( "Method 1 calk"); try {thread.sleep(1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "Method 1 don"); }}パブリッククラスのmythreadはスレッドを拡張します{private int id = 0;民間共通の共通; public mythread(string name、int no、common object){super(name); common = object; id = no; } public void run(){system.out.println( "running thread" + this.getName()); try {if(id == 0){common.synchronizedMethod1(); } else {common.method1(); }} catch(例外e){e.printstacktrace(); }} public static void main(string [] args){common c = new common(); mythread t1 = new mythread( "mythread-1"、0、c); mythread t2 = new mythread( "mythread-2"、1、c); t1.start(); t2.start(); }}これがプログラムの出力です:
Running threadmythread-1
SynchronizedMethod1が呼び出されます
Running threadmythread-2
方法1呼び出されました
SynchronizedMethod1が完了しました
方法1完了
結果は、同期されたmethod1()メソッドが実行されたとしても、method1()が呼び出されることを示しています。
9. 2つのスレッドは、オブジェクト上の2つの異なる同期インスタンスメソッドを呼び出すことができますか?
いいえ、オブジェクトがインスタンスメソッドを同期しているため、スレッドはオブジェクトのオブジェクトロックを取得します。したがって、他の同期方法は、オブジェクトロックがリリースされた後にメソッドがリリースされた後にのみ実行できます。次のコードの例は非常に明確です。一般的なクラスには、同期したMethod1()と同期したMethod2()メソッドがあり、Mythreadはこれら2つの方法を呼び出します。
public class common {public synchronized void synchronizedmethod1(){system.out.println( "synchronizedmethod1 calk"); try {thread.sleep(1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "synchronizedmethod1 done"); } public synchronized void synchronizedmethod2(){system.out.println( "synchronizedmethod2 calk"); try {thread.sleep(1000); } catch(arturnedexception e){e.printstacktrace(); } system.out.println( "synchronizedmethod2 done"); }}パブリッククラスのmythreadはスレッドを拡張します{private int id = 0;民間共通の共通; public mythread(string name、int no、common object){super(name); common = object; id = no; } public void run(){system.out.println( "running thread" + this.getName()); try {if(id == 0){common.synchronizedMethod1(); } else {common.synchronizedmethod2(); }} catch(例外e){e.printstacktrace(); }} public static void main(string [] args){common c = new common(); mythread t1 = new mythread( "mythread-1"、0、c); mythread t2 = new mythread( "mythread-2"、1、c); t1.start(); t2.start(); }}10。デッドロックとは何ですか
デッドロックとは、2つ以上のスレッドが無限にブロックされており、スレッドが必要なリソースをお互いを待っていることを意味します。これは、2つのスレッドが他のリソースのロックを取得しようとする場合に発生する可能性があり、各スレッドは、ユーザープロセスが終了しない限り、他のリソースロックのリリースを無期限に待っています。 Javaapiに関する限り、次の状況でスレッドデッドロックが発生する可能性があります。
11.死に飢えている糸とは何ですか、そしてライブロックとは何ですか?
スレッドの飢vとライフロックはデッドロックのような一般的な問題とは見なされませんが、同時プログラミングのデザイナーにとっての出会いのようなものです。
すべてのスレッドがブロックされている場合、または必要なリソースが無効であるために処理できない場合、リソースを使用できるようにするブロッキングスレッドはありません。 Javaapiのスレッドライブロックは、次の状況で発生する可能性があります。
ここでの質問は詳細ではありません。私は彼らがすべての人に役立つことを願っています。ご質問がある場合は、メッセージを残してください。編集者は、すべての人に時間内に返信します。 wulin.comのウェブサイトへのご支援ありがとうございます!