以下は、Javaスレッドに関連する人気のあるインタビューの質問です。これは、インタビューの準備に使用できます。
1)スレッドとは何ですか?
スレッドは、オペレーティングシステムが操作とスケジューリングを実行できる最小ユニットです。これはプロセスに含まれており、プロセスの実際の操作ユニットです。プログラマーはマルチプロセッサーをそれを介してプログラムすることができ、マルチスレッドを使用して操作集約型タスクをスピードアップできます。たとえば、スレッドがタスクを完了するのに100ミリ秒かかる場合、10本のスレッドを使用してタスクの変更を完了するのにスレッドが10ミリ秒しかかかりません。 Javaは、言語レベルでのマルチスレッドに優れたサポートを提供します。また、セールスポイントでもあります。詳細については、ここをクリックしてください。
2)スレッドとプロセスの違いは何ですか?
スレッドはプロセスのサブセットです。プロセスには多くのスレッドがあり、各スレッドは異なるタスクを並行して実行します。さまざまなプロセスでは、さまざまなメモリスペースを使用しますが、すべてのスレッドは同じメモリ空間を共有しています。スタックメモリで混乱しないでください。各スレッドには、ローカルデータを保存するための個別のスタックメモリがあります。詳細については、ここをクリックしてください。
3)Javaにスレッドを実装する方法は?
言語レベルには2つの方法があります。 java.lang.threadクラスのインスタンスはスレッドですが、実行するにはjava.lang.runnableインターフェイスを呼び出す必要があります。スレッドクラス自体はrunnableインターフェイスであるため、java.lang.threadクラスを継承するか、実行可能なインターフェイスを直接呼び出してrun()メソッドをオーバーライドしてスレッドを実装できます。詳細については、ここをクリックしてください。
4)実行可能またはスレッドを使用しますか?
この質問は、前の質問のフォローアップです。スレッドクラスを継承するか、実行可能なインターフェイスを呼び出すことにより、スレッドを実装できることを誰もが知っています。問題は、どの方法が優れているかということです。どのような状況で使用する必要がありますか? Javaがクラスの複数の継承をサポートしていないが、複数のインターフェイスを呼び出すことができることを知っている場合、この質問は簡単に答えることができます。したがって、他のクラスを継承したい場合は、もちろん、実行可能なインターフェイスを呼び出す方が良いでしょう。詳細については、ここをクリックしてください。
6)スレッドクラスのstart()とrun()メソッドの違いは何ですか?
この質問はよく尋ねられますが、Javaスレッドングモデルに対するインタビュアーの理解をこれから区別することができます。 start()メソッドは、新しく作成されたスレッドを起動するために使用され、run()メソッドは内部的に呼ばれます。これは、run()メソッドを直接呼び出す効果とは異なります。 run()メソッドを呼び出すと、元のスレッドでのみ呼び出されます。新しいスレッドが開始されない場合、start()メソッドは新しいスレッドを開始します。詳細については、ここをクリックしてください
7)JavaでRunnableとCallableの違いは何ですか?
実行可能で呼び出し可能な両方とも、異なるスレッドで実行されるタスクを表します。 runnableはJDK1.0以来利用可能であり、JDK1.5でCallableが追加されています。彼らの主な違いは、呼び出し可能な呼び出し()方法が値を返し、例外をスローすることができるのに対し、run()runnableの方法にはこれらの関数がないことです。 Callableは、計算結果がロードされた将来のオブジェクトを返すことができます。私のブログにはより詳細な指示があります。
8)JavaのCyclicbarrierとCountdownlatchの違いは何ですか?
CyclicBarrierとCountDownLatchの両方を使用して、スレッドのグループを他のスレッドを待機させることができます。 Cyclicbarrierとは異なり、CountDownLatchを再利用することはできません。詳細とサンプルコードを表示するには、ここをクリックしてください。
9)Javaメモリモデルとは何ですか?
Javaメモリモデルは、異なるメモリアーキテクチャ、CPU、およびオペレーティングシステムの間で決定的に動作するJavaプログラムを指定およびガイドします。マルチスレッドの状況では特に重要です。 Javaメモリモデルは、1つのスレッドによって行われた変更が他のスレッドに表示され、関係が最初に発生することを保証できます。この関係は、プログラマーを同時プログラミングでより明確にするためのいくつかのルールを定義します。たとえば、関係を持つことは最初に保証されます。
スレッド内のコードは、プログラム注文ルールと呼ばれる順番で実行できます。
同じロックの場合、ロック解除操作は、時間内に発生する別のロック操作の前に発生する必要があります。これは、管理ロックルールとも呼ばれます。
揮発性への以前の書き込み操作は、揮発性の次の読み取り操作の前であり、これは揮発性変数ルールとも呼ばれます。
スレッド内の操作は、このスレッドのstart()の後に呼び出され、スレッド開始ルールとも呼ばれます。
スレッドのすべての操作は、スレッドが終了する前に終了します。
オブジェクトの終了操作は、オブジェクトが構築された後に行う必要があります。これは、オブジェクト終了ルールとも呼ばれます。
推移的
Javaメモリモデルの理解を深めるために、「Java Concurrencyプログラミングプラクティス」の第16章を読むことを強くお勧めします。
10)Javaの揮発性変数は何ですか?
Volatileは、メンバー変数でのみ使用できる特別な修飾子です。 Java同時プログラムに同期クラスがない場合、メンバー変数のマルチスレッド操作は他のスレッドに対して透明です。揮発性変数は、前の質問の揮発性変数ルールである以前の書き込み操作の後に次の読み取り操作が発生することを保証できます。ここをクリックして、より揮発性関連のコンテンツをご覧ください。
11)スレッドの安全とは何ですか? Vectorはスレッドセーフクラスですか? (詳細についてはこちらをご覧ください)
あなたのコードがあなたがいるプロセスにある場合、同時に複数のスレッドが実行され、これらのスレッドはこのコードを同時に実行する場合があります。各実行の結果が単一のスレッド実行の結果と同じであり、他の変数の値が予想と同じである場合、それはスレッドセーフです。スレッドセーフカウンタークラスの同じインスタンスオブジェクトは、複数のスレッドで使用しても計算エラーを引き起こしません。明らかに、コレクションクラスをスレッドセーフと非スレッドセーフの2つのグループに分割できます。ベクターは同期方法を使用してスレッドセーフティを実現しますが、それに類似したアレイリストはスレッドセーフではありません。
12)Javaの人種条件は何ですか?例を挙げてください。
人種条件により、プログラムの同時状況でいくつかのバグが発生します。マルチスレッドがいくつかのリソースを競うと、人種条件が発生します。実行される最初のプログラムが失敗し、後で実行されると、プログラム全体に不確実なバグが表示されます。このようなバグは、スレッド間のランダムな競合のため、検出して再発することが困難です。例は乱れた処理です。詳細については、答えを参照してください。
13)Javaでスレッドを停止する方法は?
JavaはリッチAPIを提供しますが、スレッドを停止するためのAPIを提供しません。 JDK 1.0にはもともとは、stop()、suspend()、resume()などのいくつかの制御方法がありましたが、潜在的なデッドロックの脅威により、それらはその後のJDKバージョンで非推奨されていました。その後、Java APIのデザイナーは、スレッドを停止するための互換性のあるスレッドに安全な方法を提供しませんでした。 run()またはcall()メソッドが実行されると、スレッドは自動的に終了します。スレッドを手動で終了する場合は、揮発性ブール変数を使用してrun()メソッドループを終了するか、タスクをキャンセルしてスレッドを中断することができます。サンプルコードを表示するには、ここをクリックしてください。
14)スレッドが実行されているときに例外が発生するとどうなりますか?
これは、私がインタビューで遭遇した非常にトリッキーなJavaインタビューの質問です。簡単に言えば、例外がキャッチされていない場合、スレッドは実行を停止します。
Thread.UncaughtExceptionHandlerは、突然のスレッドの中断を引き起こす著しい例外を処理するための組み込みインターフェイスです。猛攻撃の例外がスレッドを中断すると、jvmはthread.getuncaughtexceptionhandler()を使用して、スレッドのcaughexceptionhandlerを照会し、処理のためのハンドラーのcaughtexception()メソッドのパラメーターとしてスレッドと例外を渡します。
15)2つのスレッド間でデータを共有する方法は?
これを行うには、オブジェクトを共有したり、キューをブロックするなどの同時データ構造を使用したりできます。このチュートリアル「Java Inter-Thread Communication」(2つのスレッド間でオブジェクトを共有する)は、待機と通知のメソッドを使用してプロデューサーの消費者モデルを実装します。
16)JavaのNotifyとNotifyAllの違いは何ですか?
マルチスレッドは単一の監視ロックを待つことができ、Java APIデザイナーは条件が変更されるのを待つときにそれらを通知する方法を提供するため、これはもう1つのトリッキーな問題です。 notify()メソッドは特定のスレッドを覚ますことができないため、1つのスレッドが待っているときにのみ機能します。 NotifyAll()はすべてのスレッドを目覚めさせ、少なくとも1つのスレッドが実行され続けることができるようにロックを競うことを可能にします。私のブログには、より詳細な情報とサンプルコードがあります。
17)スレッドクラスではなく、メソッドを待機、通知、および通知するのはなぜですか?
これは、既存のシステムに対するインタビュアーの認識と、一般的であるが不合理と思われるものを調べる設計関連の質問です。これらの質問に答えるときは、これらのメソッドをオブジェクトクラスに入れるのが理にかなっている理由を説明する必要があります。明らかな理由の1つは、Javaが提供するロックがスレッドレベルではなくオブジェクトレベルであり、各オブジェクトにはスレッドを介して取得されるロックがあることです。スレッドがロックを待つ必要がある場合、オブジェクトのwait()メソッドを呼び出すことは理にかなっています。 wait()メソッドがスレッドクラスで定義されている場合、スレッドが待機しているロックを明らかにしません。簡単に言えば、待機、Notify、NotifyAllはロックレベルの操作であるため、ロックがオブジェクトに属しているため、オブジェクトクラスで定義されます。詳細については、この記事をご覧ください。
18)Threadlocal変数とは何ですか?
ThreadlocalはJavaの特別な変数です。各スレッドにはスレッドローカルがあります。つまり、各スレッドには独自の独立変数があり、レース条件は完全に排除されます。高価なオブジェクトを作成するためのスレッドセーフを取得するのに最適な方法です。たとえば、ThreadLocalを使用してSimpleDateFormat Thread-Safeを作成することができます。そのクラスは作成するのに費用がかかり、各呼び出しに対して別のインスタンスを作成する必要があるため、ローカルで使用する価値はありません。各スレッドに変数の一意のコピーを提供すると、効率が大幅に向上します。まず、作成された高価なオブジェクトの数は多重化により削減されます。第二に、費用のかかる同期や不変性を使用せずにスレッドの安全性を獲得します。スレッドローカル変数のもう1つの良い例は、マルチスレッド環境で作成された高価なランダムオブジェクトの数を減らすThreadLocalrandomクラスです。詳細については、回答をご覧ください。
19)FutureTaskとは何ですか?
Java Concurrentプログラムでは、FutureTaskはキャンセルできる非同期操作を表しています。操作の開始とキャンセル、操作が完了したかどうかのクエリ、操作結果の取得などの方法があります。結果は、操作が完了したときにのみ取得できます。操作が完了していない場合、GETメソッドがブロックされます。 FutureTaskオブジェクトは、呼び出し可能で実行可能なオブジェクトをラップできます。 FutureTaskは実行可能なインターフェイスも呼び出すため、実行のためにエグゼキューターに提出できます。
20)Javaの中断されたメソッドと中断のメソッドの違いは何ですか?
割り込まれた()とIS介入()の主な違いは、前者が割り込み状態をクリアしますが、後者はそうしないことです。 Javaマルチスレッドの割り込みメカニズムは、内部識別子を使用して実装されています。 thread.interrupt()を呼び出してスレッドを中断すると、割り込み識別子がtrueに設定されます。割り込みスレッドが静的メソッドスレッドを呼び出すと、中断()が割り込み状態を確認すると、割り込み状態がクリアされます。非静的な方法は、()を使用して、割り込みステータス識別子を変更せずに他のスレッドの割り込みステータスを照会します。簡単に言えば、中断のあるエクセプトをスローする方法は、割り込み状態をクリアします。いずれにせよ、スレッドの割り込み状態は、割り込みを呼び出す他のスレッドによって変更される場合があります。
21)なぜ待機し、通知メソッドを同期ブロックで呼び出す必要があるのですか?
これは主にJava APIがこれを強制し、そうでない場合、コードがIllegalMonitorStateExceptionの例外をスローするためです。もう1つの理由は、待機と通知の間の人種条件を避けることです。
22)なぜループの待機条件を確認する必要があるのですか?
待機状態のスレッドは、エラーアラートと擬似対策を受ける場合があります。待機条件がループでチェックされていない場合、プログラムは終了条件を満たさずに終了します。したがって、待っているスレッドが目覚めると、元の待機状態がまだ有効であると考えることはできません。また、notify()メソッド呼び出しの後、待機スレッドが目覚める前にこの期間中に変化する可能性があります。これが、ループでwait()メソッドを使用すると、Eclipseでテンプレートを作成して待機を呼び出して通知して試してみることができる理由です。この問題について詳しく知りたい場合は、本「Effection Java」のスレッドと同期の章を読むことをお勧めします。
23)Javaの同期コレクションと同時コレクションの違いは何ですか?
同期コレクションと同時コレクションの両方は、マルチスレッドと同時性に適したスレッドセーフコレクションを提供しますが、同時コレクションはよりスケーラブルです。 Java 1.5の前に、プログラマーは同期コレクションのみを使用し、マルチスレッドの並行性が寄与した場合、システムのスケーラビリティを妨害し、競合につながります。 Java5は、CONCURRENTHASHMAPなどの同時コレクションを導入します。これは、スレッドの安全性を提供するだけでなく、ロック分離や内部ゾーンなどの最新のテクノロジーでスケーラビリティを向上させます。詳細については、答えをご覧ください。
24)Javaのヒープとスタックの違いは何ですか?
なぜこの質問は、マルチスレッドと同時のインタビューの質問に分類されるのですか?スタックはスレッドに密接に関連するメモリ領域であるためです。各スレッドには独自のスタックメモリがあり、ローカル変数、メソッドパラメーター、およびスタックコールを保存するために使用されます。 1つのスレッドに保存されている変数は、他のスレッドには見えません。ヒープは、すべてのスレッドで共有される一般的なメモリ領域です。オブジェクトはヒープで作成されます。効率を向上させるために、スレッドはヒープから独自のスタックにAをキャッシュします。複数のスレッドがこの変数を使用する場合、問題を引き起こす可能性があります。現時点では、揮発性変数が役割を果たすことができ、メインメモリから変数の値を読み取るためにスレッドが必要です。
詳細については、答えをご覧ください。
25)スレッドプールとは何ですか?なぜそれを使うのですか?
スレッドを作成するには、高価なリソースと時間がかかります。タスクが来た後にのみスレッドが作成された場合、応答時間は長くなり、プロセスは限られた数のスレッドを作成できます。これらの問題を回避するために、プログラムの開始時に応答して処理するためにいくつかのスレッドが作成されます。それらはスレッドプールと呼ばれ、内部のスレッドはワーカースレッドと呼ばれます。 JDK1.5から始めて、Java APIは、異なるスレッドプールを作成できるエグゼキューターフレームワークを提供します。たとえば、一度に1つのタスクを処理する単一のスレッドプール。固定数のスレッドプールまたはキャッシュスレッドプール(短命のタスクを備えた多くのプログラムに適した拡張可能なスレッドプール)。詳細については、この記事をご覧ください。
26)プロデューサーと消費者の問題を解決するためのコードを書く方法は?
実際には、あなたが解決するスレッドの問題の多くは、プロデューサーの消費者モデルに属します。つまり、1つのスレッド生産タスクは他のスレッドによる消費のためです。この問題を解決するためにスレッド間で通信する方法を知っている必要があります。比較的低レベルの方法は、待機を使用してこの問題を解決するために通知することです。より優れた方法は、セマフォまたはブロッキングキューを使用して生産者と消費者モデルを実装することです。このチュートリアルはそれを実装します。
27)デッドロックを避ける方法は?
Javaマルチスレッドのデッドロック
デッドロックとは、リソースの競争により、実行プロセス中に2つ以上のプロセスによって引き起こされる相互待機の現象を指します。外力がなければ、継続することはできません。これは深刻な問題です。なぜなら、デッドロックはプログラムを一時停止し、タスクを完了することができないからです。デッドロックの発生のために、次の4つの条件を満たす必要があります。
相互除外条件:リソースは、一度に1つのプロセスでのみ使用できます。
リクエストと保持条件:リソースを要求するためにプロセスがブロックされると、取得したリソースを保持します。
奪われない条件:プロセスによって得られたリソースは、使用終了まで強制的に奪われることはできません。
ループ待機条件:ループ待機リソース関係は、頭と尾で接続されているいくつかのプロセスの間に形成されます。
デッドロックを回避する最も簡単な方法は、ループの待機条件を防ぎ、システム内のすべてのリソースを整理し、すべてのプロセスアプリケーションリソースを特定の順序で操作(昇順または下降順序で操作する必要があることを規定することです。このチュートリアルには、デッドロックの回避に関するコードの例とディスカッションの詳細があります。
28)Javaのライブロックとデッドロックの違いは何ですか?
これは前の質問の拡張です。ライブロックはデッドロックに似ています。違いは、ライブロックのスレッドまたはプロセスの状態が常に変化していることです。ライブロックは、特別な種類の空腹と見なすことができます。ライブロックの現実的な例は、2人が狭い廊下で会うときです。どちらもお互いを回避して、お互いが通過できるようにしようとしますが、回避の方向が同じであるため、最終的に誰も廊下を通り抜けることはできません。簡単に言えば、ライブロックとデッドロックの主な違いは、以前のプロセスの状態を変更できるが、実行し続けることができないことです。
29)スレッドにロックがあるかどうかを検出する方法は?
電話インタビューに参加するまで、スレッドにロックがあるかどうかを実際に検出できるとは知りませんでした。 java.lang.threadにはholdslock()と呼ばれるメソッドがあります。これは、現在のスレッドが特定のオブジェクトのロックを所有している場合にのみtrueを返します。詳細については、この記事をご覧ください。
30)Javaでスレッドスタックをどのように入手しますか?
さまざまなオペレーティングシステムの場合、Javaプロセスのスレッドスタックを取得するには複数の方法があります。スレッドスタックを取得すると、JVMはすべてのスレッドの状態をログファイルに保存するか、コンソールに出力します。 Windowsでは、Ctrl + Break Keyの組み合わせを使用してスレッドスタックを取得し、LinuxでKill -3コマンドを使用できます。 JSTackツールを使用して、スレッドIDで動作するそれを取得することもできます。また、JPSツールを使用してIDを見つけることもできます。
31)JVMのパラメーターは、小さなスタックでスレッドのスタックを制御するために使用されます
この問題は非常に単純で、-XSSパラメーターはスレッドのスタックサイズを制御するために使用されます。このパラメーターの詳細については、JVM構成リストを表示できます。
32)Javaの同期とReentrantLockの違いは何ですか?
Javaは、同期されたキーワードを通じて長い間相互排除を達成することができ、いくつかの欠点があります。たとえば、ロック以外のメソッドやブロックの境界を拡張することはできません。ロックなどを取得しようとするときに中途半端にキャンセルすることはできません。Java5は、ロックインターフェイスを介してこれらの問題を解決するためのより複雑なコントロールを提供します。 ReentrantLockクラスはロックを実装します。ロックは、同期したものと同じ並行性とメモリセマンティクスを備えており、拡張可能です。詳細については、この記事をご覧ください
33)3つのスレッドT1、T2、およびT3があります。それらが順番に実行されることを確認する方法は?
マルチスレッドで特定の順序でスレッドを実行できるようにするには多くの方法があります。スレッドクラスのJoin()メソッドを使用して1つのスレッドで別のスレッドを起動することができ、別のスレッドがスレッドを完了して実行を継続します。 3つのスレッドの順序を確保するには、最後の1つを最初に開始する必要があります(T3はT2を呼び出し、T2はT1を呼び出します)。これにより、T1が最初に完了し、T3が最後に完了します。詳細については、この記事をご覧ください。
34)スレッドクラスの収量法の機能は何ですか?
利回り方法は、現在実行中のスレッドオブジェクトを一時停止し、同じ優先度を持つ他のスレッドが実行されることを許可します。これは静的な方法であり、現在のスレッドがCPUの使用を放棄し、他のスレッドがCPUを占有できることを保証することはできません。 rews()を実行するスレッドは、一時停止状態に入った直後に実行される場合があります。収穫方法の詳細については、ここをクリックしてください。
35)JavaのCONCURRENTHASHMAPの同時性は何ですか?
concurrenthashmapは、実際のマップをいくつかの部分に分割して、スケーラビリティとスレッドの安全性を実現します。この分割は、マルチスレッドの状況での競合を回避できるように、デフォルト値が16の同時パラメーターである同時性を使用して取得されます。より並行性と内部サイズ変更については、JavaでConcurrenthashmapがどのように機能するかを私の記事を読んでください。
36)Javaのセマフォとは何ですか?
Javaのセマフォは、カウントシグナルである新しい同期クラスです。概念的には、概念的には、セマフォは一連の許可を維持しています。必要に応じて、ライセンスが取得される前に、各獲得()が利用可能になる前にブロックされます。各リリース()は許可を追加し、ブロッキング取得者をリリースする場合があります。ただし、実際のライセンスオブジェクトを使用せずに、Semaphoreは利用可能なライセンス番号のみをカウントし、対応するアクションを実行します。セマフォは、データベース接続プールなどのマルチスレッドコードでよく使用されます。詳細については、ここをクリックしてください。
37)タスクを送信すると、スレッドプールキューがいっぱいです。それが起こるとどうなりますか?
この質問はcraftなものであり、多くのプログラマーは、スレッドプールキューにスペースがあるまでタスクがブロックされると考えるでしょう。実際、タスクを実行するようにスケジュールできない場合、ThreadPoolExecutorのSubmit()メソッドは拒否ExecutionExceptionの例外をスローします。
38)Javaスレッドプールのsubmit()とexecute()メソッドの違いは何ですか?
どちらの方法でも、タスクをスレッドプールに送信できます。 execute()メソッドのreturnタイプはvoidであり、これはexecutorインターフェイスで定義され、submit()メソッドは計算結果を保持している将来のオブジェクトを返すことができます。 ExecutorServiceインターフェイスで定義されています。エグゼキューターインターフェイスを拡張します。 ThreadPoolexecutorやScheduledThreadPoolexecutorなどの他のスレッドプールクラスには、これらの方法があります。詳細については、ここをクリックしてください。
39)ブロッキング方法とは何ですか?
ブロッキング方法は、プログラムがメソッドが完了するのを待つことを意味し、他に何もしません。 ServersocketのAccept()メソッドは、クライアントが接続するのを待つことです。ここでのブロックは、呼び出し結果が返される前に現在のスレッドが中断され、結果が得られるまで戻らないことを意味します。さらに、タスクが完了する前に戻る非同期および非ブロッキングメソッドがあります。詳細については、ここをクリックしてください。
40)スウィングスレッドセーフですか?なぜ?
あなたは前向きな答えを与えることができます、スイングはスレッドセーフではありませんが、インタビュアーがあなたに理由を尋ねなかったとしても、この答えがなぜであるのかを説明する必要があります。スイングはスレッドセーフではないと言うとき、しばしばマルチスレッドで変更できないコンポーネントに言及します。 GUIコンポーネントのすべての更新は、AWTスレッドで完了する必要があります。 Swingは、更新する2つの同期と非同期のコールバックメソッドを提供します。ここをクリックして、スイングとスレッドの安全関連コンテンツを詳細に確認してください。
41)JavaのInvokeandwaitとInvokelaterの違いは何ですか?
これらの2つの方法は、Swing APIによってJava開発者に提供され、イベントディスパッチスレッドではなく現在のスレッドからGUIコンポーネントを更新します。 InvokeandWait()は、進行状況バーなどのGUIコンポーネントを同期して更新します。進行状況が更新されると、それに応じて進行状況バーも変更する必要があります。進行状況が複数のスレッドで追跡される場合、InvokeandWait()メソッドが呼び出され、イベントディスパッチスレッドにそれに応じてコンポーネントを更新します。 Invokelater()メソッドは、コンポーネントを更新するために非同期に呼ばれます。詳細については、ここをクリックしてください。
42)スレッドセーフはスイングAPIのどのような方法ですか?
この質問は、スイングとスレッドの安全性についても言及しています。コンポーネントはスレッドセーフではありませんが、Repaint()やRevalidate()など、マルチスレッドできるように呼ばれる方法がいくつかあります。 jTextComponentのsettext()メソッドとinsert()およびappend()jtextareaのメソッドもスレッドセーフです。
43)Javaで不変のオブジェクトを作成する方法は?
この問題はマルチスレッドとは何の関係もないようですが、不変性はすでに複雑な同時プログラムを簡素化するのに役立ちます。不変のオブジェクトは、同期せずに共有でき、オブジェクトへの同時アクセスの場合、同期オーバーヘッドを減らします。ただし、Javaには@immutable Annotationがありません。不変のクラスを作成するには、次の手順を実装する必要があります。コンストラクターを介してすべてのメンバーを初期化し、変数にセッターメソッドを提供せず、すべてのメンバーをプライベートと宣言して、これらのメンバーが直接アクセスできるようにします。 Getterメソッドでは、オブジェクト自体を直接返すのではなく、オブジェクトをクローンしてオブジェクトのコピーを返します。私の記事Javaでオブジェクトを不変にする方法には、詳細なチュートリアルがあり、読んだ後は自信に満ちていることができます。
44)JavaのReadWritelockとは何ですか?
一般的に言えば、読み取りと書き込みロックは、同時プログラムのパフォーマンスを向上させるために使用されるロック分離技術の結果です。 JavaのReadWriteLockは、Java 5に追加された新しいインターフェイスです。ReadWriteLockは、関連するロックのペアを維持します。読み取りロックは、書き込みスレッドなしで複数の読み取りスレッドによって同時に保持される場合があります。 Write Locksは排他的です。JDKでReentranTreadWritelockを使用してこのルールを実装できます。これは、最大65535の書き込みロックと65535の読み取りロックをサポートします。
45)マルチスレッドの忙しいループとは何ですか?
ビジーループは、プログラマーがループを使用してスレッドを待つことです。 wait()、sleep()、hied hieds()などの従来の方法とは異なり、それらはすべてCPUコントロールを放棄しますが、ビジーループはCPUを放棄しませんが、空のループを実行しているだけです。これの目的は、CPUキャッシュを保存することです。マルチコアシステムでは、スレッドが目覚めるのを待っている人は、キャッシュを再構築する別のカーネルで実行される場合があります。キャッシュの再構築を避け、再構築を待つ時間を短縮するために利用できます。詳細については、この記事を確認できます。
46)揮発性変数と原子変数の違いは何ですか?
これは興味深い質問です。まず、揮発性変数は原子変数と非常によく似ていますが、関数は異なります。揮発性変数は、前身の関係を保証します。つまり、書き込み操作はその後の読み取り操作の前に発生しますが、原子性を保証するものではありません。たとえば、揮発性のあるカウント変数を変更すると、カウント++操作は原子ではありません。 AtomicIntegerクラスが提供する原子法は、この操作をAtomicにすることができます。たとえば、getandincrement()メソッドはアトミック増分操作を実行して現在の値を1つだけ追加し、他のデータ型と参照変数も同様の操作を実行できます。
47)同期ブロック内のスレッドが例外をスローするとどうなりますか?
この質問は、多くのJavaプログラマーをだましました。ロックがこの手がかりを解放するかどうかを考えることができれば、それでも正しく答えることを望んでいます。同期ブロックが正常に終了するか異常に終了するかに関係なく、内部のスレッドはロックを放出するため、ロックを解放するためにエネルギーを費やす必要がないため、ロックインターフェイスと比較して同期ブロックを好みます。この関数は、最終的にブロックでロックを解放することで実装できます。
48)シングルトンモードのダブルチェックロックは何ですか?
この質問はJavaのインタビューでよく尋ねられますが、インタビュアーはこの質問に答えることに50%しか満足していません。半数の人がダブルチェックロックを書くことができず、半分の人はそれが隠された危険とJava 1.5がそれをどのように修正したかを知ることができません。実際、スレッドセーフシングルトンを作成するのは古い方法です。 Singletonインスタンスが最初に作成されると、単一のロックでパフォーマンスを最適化しようとしますが、複雑すぎるため、JDK1.4で失敗し、個人的にも気に入らない。とにかく、たとえあなたがそれを気に入らなくても、あなたはまだそれがよく尋ねられるのでそれを理解する必要があります。詳細については、Singleton WorksのRocking on Singleton Worksのロックを再確認する方法を確認できます。
49)Javaでスレッドセーフシングルトンを作成する方法は?
これは上記の質問のフォローアップです。ダブルチェックロックが好きではなく、インタビュアーがSingletonクラスを作成する代替方法について尋ねた場合、JVMクラスの読み込みと静的変数の初期化機能を使用してSingletonインスタンスを作成するか、列挙タイプを使用してSingletonを作成できます。私はこの方法が好きです。詳細については、この記事を確認できます。
50)あなたが従う3つのマルチスレッドのベストプラクティスを書きます
私はこの種の問題が最も好きで、パフォーマンスを改善するために同時コードを書くときに特定のベストプラクティスに従うと思います。ここに、ほとんどのJavaプログラマーが従うべき3つのベストプラクティスが次のとおりです。
スレッドに意味のある名前を付けてください。
これにより、バグを見つけたり追跡したりできます。 OrderProcessor、QuoteProcessor、またはTradeProcessorこの名前は、スレッド1よりもはるかに優れています。スレッド2およびスレッド3。スレッドに、完了したいタスクに関連する名前を付けます。すべての主要なフレームワーク、さらにはJDKでさえ、このベストプラクティスに従います。
同期の範囲をロックして狭めることは避けてください
ロックは高価であり、コンテキストの切り替えはより時間がかかります。同期とロックを使用して、重要な領域を最小限に抑えてみてください。したがって、同期法よりも同期ブロックを好むので、ロックを絶対に制御できます。
より多くの同期クラスを使用し、より少ない待機を使用して通知します
まず、CountDownLatch、Semaphore、CyclicBarrier、およびExchanger同期クラスがコーディング操作を簡素化しますが、WAITとNOTIFYで複雑な制御フローを制御することは困難です。第二に、これらのクラスは、最高の企業によって書かれ、維持されています。それらは、その後のJDKで最適化および改善され続けます。これらの高レベルの同期ツールを使用して、プログラムを努力せずに最適化できます。
より多くの同時セットとより少ない同期セットを使用します。これはもう1つのわかりやすいベストプラクティスです。同時セットは同期セットよりもスケーラブルであるため、同時のプログラミングには同時セットを使用する方が適しています。次回マップを使用する必要がある場合は、まずconcurrenthashmapを使用することを検討する必要があります。私の記事Java Concurrentコレクションには、より詳細な説明があります。
51)スレッドを起動する方法は?
この問題は、Java Garbage Collectionを強制する方法のようなものです。まだそれをする方法はありません。 System.gc()を使用してゴミコレクションを実行することはできますが、成功することは保証されていません。 Javaでスレッドを強制的に開始する方法はありません。スレッドスケジューラによって制御され、Javaは関連するAPIを公開しません。
52)JavaのFork結合フレームワークは何ですか?
fork join 框架是JDK7 中出现的一款高效的工具,Java 开发人员可以通过它充分利用现代服务器上的多处理器。它是专门为了那些可以递归划分成许多子模块设计的,目的是将所有可用的处理能力用来提升程序的性能。fork join 框架一个巨大的优势是它使用了工作窃取算法,可以完成更多任务的工作线程可以从其它线程中窃取任务来执行。你可以查看这篇文章获得更多信息。
53) Java 多线程中调用wait () 和sleep ()方法有什么不同?
Java 程序中wait 和sleep 都会造成某种形式的暂停,它们可以满足不同的需要。wait ()方法用于线程间通信,如果等待条件为真且其它线程被唤醒时它会释放锁,而sleep ()方法仅仅释放CPU 资源或者让当前线程停止执行一段时间,但不会释放锁。你可以查看这篇文章获得更多信息。