BATは面接問題のマルチスレッド/高同時性をよく聞きます
1.stop()とsuspend()メソッドはなぜ推奨されないのですか?
stop()の使用に反対するのは、安全ではないからです.スレッドによって取得されたすべてのロックが解除され、オブジェクトが一貫性のない状態にある場合、他のスレッドはその状態でチェックおよび変更できます.その結果、本当の問題点を検出するのは難しい.
suspend()メソッドはデッドロックが発生しやすい.suspend()を呼び出すと、ターゲットスレッドは停止しますが、その前に取得したロックは保持されます.「保留中」のスレッドが実行を再開しない限り、ロックされたリソースには他のスレッドはアクセスできません.任意のスレッドでは、ターゲットスレッドを復元しながらロックされたリソースを使用しようとすると、デッドロックになります.したがって、suspend()を使用するのではなく、スレッドがアクティブになるか保留するかを示すフラグを自分のThreadクラスに配置する必要があります.フラグがスレッドが保留されるべきであることを示すと、wait()で待機状態に入るように命令します.フラグがスレッドを復元すべきであることを示す場合は、notify()でスレッドを再起動します.
2.sleep()とwait()の違いは何ですか?
sleepは実行中のスレッドがアクティブにcpuを譲渡し、cpuは他のスレッドを実行し、sleepが指定した時間後、cpuはこのスレッドに戻って下に実行し続け、現在のスレッドが同期ロックに入った場合、sleepメソッドはロックを解放しません.現在のスレッドがsleepメソッドを使用してcpuを譲渡しても、しかし、同期ロックによってブロックされた他のスレッドも実行できません.waitとは、同期ロックに入ったスレッド内で、他のロックを待っているスレッドが同期ロックを取得して実行できるように、同期ロックを一時的に譲渡することを意味します.他のスレッドだけがnotifyメソッドを呼び出した(notifyはロックを解放しないが、waitメソッドを呼び出したスレッドがロック獲得の競争に参加できることを教えただけだが、すぐにロックを得るわけではない.ロックはまだ他の人の手にあるので、他の人はまだ解放していない.notify
メソッドの後ろのコードはまだたくさんありますが、これらのコードが実行されてからロックを解除する必要があります.notfiyメソッドの後に待機といくつかのコードを追加して、効果を見ることができます).waitメソッドを呼び出すスレッドはwait状態を解除し、プログラムは再びロックを得てから下に実行し続けることができます.
3.同期と非同期はどのような違いがあり、どのような場合にそれぞれ使用しますか?
データがスレッド間で共有される場合.例えば、書き込み中のデータが後で別のスレッドに読み出されたり、読み取り中のデータが別のスレッドに書き込まれたりすると、これらのデータは共有データであり、同期アクセスが必要になります.
アプリケーションがオブジェクト上で実行に時間がかかるメソッドを呼び出し、メソッドの戻りをプログラムに待たせたくない場合は、非同期プログラミングを使用する必要があります.多くの場合、非同期パスを使用すると効率的になります.
4.スレッドがオブジェクトのsynchronizedメソッドに入ると、他のスレッドはオブジェクトの他のメソッドに入ることができますか?
他のメソッドの前にsynchronizedキーワードが追加されているかどうか、追加されていない場合は可能です.このメソッドの内部でwaitが呼び出された場合、他のsynchronizedメソッドにアクセスできます.他のメソッドにsynchronizedキーワードが追加され、内部でwaitが呼び出されていない場合はできません.他の方法がstaticの場合、その同期ロックは現在のクラスのバイトコードであり、非静的な方法はthisを使用するため、非静的な方法と同期できない.
5.synchronizedとjavaを簡単に述べる.util.concurrent.locks.ロックの異同?
主な同じ点:ロックはsynchronizedが実現したすべての機能を完成することができます.
主な相違点:Lockはsynchronizedよりも正確なスレッドの意味とより良い性能を持っている.synchronizedは自動的にロックを解放しますが、ロックはプログラマーに手動で解放するように要求し、finallyで
文から解放する.ロックにはさらに強力な機能があります.例えば、tryロック方法はロックをブロックしないで取ることができます.
例を挙げて説明する(以下の問題をlockで書き換えた)
i
6.スレッドのいくつかの利用可能な状態を概括的に説明する.
新規new.準備は実行可能なスレッドプールに配置され、スレッドスケジューリングによって選択され、cpuを取得するのを待つ.ジルコニウム運転はcpuを得た.閉塞
oブロック実行wait()を待つ.o同期ブロック取得オブジェクトの同期が煩雑な場合、同期ロックは他のスレッドに占有される.o他のブロックはsleep()またはjoin()メソッドを実行する.死.
7.ThreadLocalとは?
ThreadLocalはスレッドのローカル変数を作成するために使用され、オブジェクトのすべてのスレッドがグローバル変数を共有することを知っています.したがって、これらの変数はスレッドが安全ではありません.同期技術を使用することができます.しかし、同期を使用したくない場合は、ThreadLocal変数を選択できます.
各スレッドには、get()set()メソッドを使用してデフォルト値を取得したり、スレッド内で値を変更したりする独自のThread変数があります.ThreadLocalインスタンスは、通常、スレッドステータスに関連付けられてprivate staticプロパティであることを望んでいます.
8.run()とstart()の違い.
run():通常のrunメソッドを呼び出すだけ
start():スレッドが開始され、Jvmによってrunメソッドが呼び出されます.
スレッドを開始するにはstart()メソッドを呼び出し、スレッドが表す仮想プロセッサを実行可能にします.これは、JVMによってスケジュールされ、実行できることを意味します.これは、スレッドがすぐに実行されるという意味ではありません.run()メソッドは、スレッドを停止するために終了しなければならないフラグを生成することができる.
9.あなたが知っているスレッドの同期方法を教えてください.
wait():スレッドを待機状態にし、持つオブジェクトのlockを解放します.sleep():実行中のスレッドをスリープ状態にする静的メソッドで、InterruptedException例外をキャプチャするために呼び出されます.notify():待機中のスレッドを起動します.このメソッドを呼び出すと、待機中のスレッドを正確に起動するのではなく、JVMによって起動するスレッドを決定し、優先度ではありません.notityAll():すべての待機状態にあるスレッドを起動します.すべての起動スレッドにオブジェクトのロックを与えるのではなく、競合させることに注意してください.
10.スレッドスケジューリングとスレッド制御.
スレッドのスケジュール(優先度):
スレッドのスリープと同様に、スレッドの優先度はスレッドの実行順序を保証できません.ただし,優先度の高いスレッドはCPUリソースを取得する確率が高く,優先度の低いスレッドは実行する機会がないわけではない.スレッドの優先度は1~10の整数で表され、数値が大きいほど優先度が高くなり、デフォルトの優先度は5です.1つのスレッドで別の新しいスレッドを開くと、新しいスレッドはそのスレッドのサブスレッドと呼ばれ、サブスレッドの初期優先度は親スレッドと同じです.
スレッド制御
sleep()/スレッドスリープjoin()/スレッド加入yield()/スレッド礼譲setDaemon()/スレッドガード
割り込みスレッド
stop()interrupt()(最初に選択)
11.スレッド飢え死にとは何ですか.ロックとは何ですか.
すべてのスレッドがブロックされている場合、または必要なリソースが無効であるため処理できない場合、非ブロックスレッドが存在しないため、リソースが使用可能になります.JavaAPIでスレッド・ロックが発生する可能性があります.
すべてのスレッドがシーケンスでObjectを実行する.wait(0)、パラメータが0のwaitメソッド.プログラムは、対応するオブジェクトにスレッド呼び出しObjectがあるまでライフロックを発行する.notify()またはObject.notifyAll(). すべてのスレッドが無限ループに詰まっている場合.
12.マルチスレッドのビジーサイクルは何ですか?
ビジーサイクルとは、プログラマがループでスレッドを待機させることであり、従来の方法wait()やsleep()やyield()のようにCPU制御を放棄し、ビジーサイクルはCPUを放棄することなく、空のループを実行します.この目的はCPUキャッシュを保持することである.
マルチコアシステムでは、スレッドが目が覚めるのを待っている間に別のカーネルで実行される可能性があります.これにより、キャッシュが再構築されます.キャッシュの再構築を回避し、再構築を待つ時間を減らすために使用できます.
13.volatile変数は何ですか.volatile変数とatomic変数の違いは何ですか?
volatileは修飾された変数の可視性を保証する.volatileはマルチスレッドにおける同じ変数の可視性を保証するだけであるため,スイッチング状態としての変数,すなわちBooleanタイプを修飾するための変数であることが多い.
volatileは、類似スイッチタイプの変数を修飾するために使用されることが多く、Atomicは、類似カウンタ関連の変数、他のマルチスレッド同時動作synchronizedキーワード修飾に使用されることが多い.
volatileには2つの機能があります.
この変数は複数のスレッドにコピーが存在せず,メモリから直接読み出す.このキーワードは、命令の再ソート最適化を禁止します.すなわち、volatile変数の付与操作の後にメモリバリア(生成されたアセンブリコード)があり、読み取り操作がメモリバリアの前に並べ替えられない.
14.volatileタイプ変数はどのような保証を提供しますか?非原子操作を原子操作に変えることができますか?
volatileはhappens-beforeの保証を提供し、1つのスレッドの修正が他のスレッドに表示されることを保証します.
Javaではlongとdoubleを除くすべての基本タイプの読み取りと付与は原子的な操作です.一方,64ビットのlongとdouble変数は,JVMによって2つの分離された32ビットとして動作するため,原子性を持たず,ワード引き裂き問題を生じる.しかし、longまたはdouble変数を定義すると、volatileキーワードを使用すると、(単純な付与と戻り操作の)原子性が得られます.
stop()の使用に反対するのは、安全ではないからです.スレッドによって取得されたすべてのロックが解除され、オブジェクトが一貫性のない状態にある場合、他のスレッドはその状態でチェックおよび変更できます.その結果、本当の問題点を検出するのは難しい.
suspend()メソッドはデッドロックが発生しやすい.suspend()を呼び出すと、ターゲットスレッドは停止しますが、その前に取得したロックは保持されます.「保留中」のスレッドが実行を再開しない限り、ロックされたリソースには他のスレッドはアクセスできません.任意のスレッドでは、ターゲットスレッドを復元しながらロックされたリソースを使用しようとすると、デッドロックになります.したがって、suspend()を使用するのではなく、スレッドがアクティブになるか保留するかを示すフラグを自分のThreadクラスに配置する必要があります.フラグがスレッドが保留されるべきであることを示すと、wait()で待機状態に入るように命令します.フラグがスレッドを復元すべきであることを示す場合は、notify()でスレッドを再起動します.
2.sleep()とwait()の違いは何ですか?
sleepは実行中のスレッドがアクティブにcpuを譲渡し、cpuは他のスレッドを実行し、sleepが指定した時間後、cpuはこのスレッドに戻って下に実行し続け、現在のスレッドが同期ロックに入った場合、sleepメソッドはロックを解放しません.現在のスレッドがsleepメソッドを使用してcpuを譲渡しても、しかし、同期ロックによってブロックされた他のスレッドも実行できません.waitとは、同期ロックに入ったスレッド内で、他のロックを待っているスレッドが同期ロックを取得して実行できるように、同期ロックを一時的に譲渡することを意味します.他のスレッドだけがnotifyメソッドを呼び出した(notifyはロックを解放しないが、waitメソッドを呼び出したスレッドがロック獲得の競争に参加できることを教えただけだが、すぐにロックを得るわけではない.ロックはまだ他の人の手にあるので、他の人はまだ解放していない.notify
メソッドの後ろのコードはまだたくさんありますが、これらのコードが実行されてからロックを解除する必要があります.notfiyメソッドの後に待機といくつかのコードを追加して、効果を見ることができます).waitメソッドを呼び出すスレッドはwait状態を解除し、プログラムは再びロックを得てから下に実行し続けることができます.
3.同期と非同期はどのような違いがあり、どのような場合にそれぞれ使用しますか?
データがスレッド間で共有される場合.例えば、書き込み中のデータが後で別のスレッドに読み出されたり、読み取り中のデータが別のスレッドに書き込まれたりすると、これらのデータは共有データであり、同期アクセスが必要になります.
アプリケーションがオブジェクト上で実行に時間がかかるメソッドを呼び出し、メソッドの戻りをプログラムに待たせたくない場合は、非同期プログラミングを使用する必要があります.多くの場合、非同期パスを使用すると効率的になります.
4.スレッドがオブジェクトのsynchronizedメソッドに入ると、他のスレッドはオブジェクトの他のメソッドに入ることができますか?
他のメソッドの前にsynchronizedキーワードが追加されているかどうか、追加されていない場合は可能です.このメソッドの内部でwaitが呼び出された場合、他のsynchronizedメソッドにアクセスできます.他のメソッドにsynchronizedキーワードが追加され、内部でwaitが呼び出されていない場合はできません.他の方法がstaticの場合、その同期ロックは現在のクラスのバイトコードであり、非静的な方法はthisを使用するため、非静的な方法と同期できない.
5.synchronizedとjavaを簡単に述べる.util.concurrent.locks.ロックの異同?
主な同じ点:ロックはsynchronizedが実現したすべての機能を完成することができます.
主な相違点:Lockはsynchronizedよりも正確なスレッドの意味とより良い性能を持っている.synchronizedは自動的にロックを解放しますが、ロックはプログラマーに手動で解放するように要求し、finallyで
文から解放する.ロックにはさらに強力な機能があります.例えば、tryロック方法はロックをブロックしないで取ることができます.
例を挙げて説明する(以下の問題をlockで書き換えた)
i
mport java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ThreadTest {
/**
* @param args
*/
private int j;
private Lock lock = new ReentrantLock();
public static void main(String[] args) {
// TODO Auto-generated method stub ThreadTest tt = new ThreadTest(); for(int i=0;i<2;i++)
{
new Thread(tt.new Adder()).start();
new Thread(tt.new Subtractor()).start();
}
}
private class Subtractor implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
/*synchronized (ThreadTest.this) { System.out.println("j--=" + j--);
// , ?
}*/ lock.lock(); try
{
System.out.println("j--=" + j--);
}finally
{
lock.unlock();
}
}
}
}
private class Adder implements Runnable
{
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
/*synchronized (ThreadTest.this) { System.out.println("j++=" + j++);
}*/ lock.lock(); try
{
System.out.println("j++=" + j++);
}finally
{
lock.unlock();
}
}
}
}
}
6.スレッドのいくつかの利用可能な状態を概括的に説明する.
新規new.準備は実行可能なスレッドプールに配置され、スレッドスケジューリングによって選択され、cpuを取得するのを待つ.ジルコニウム運転はcpuを得た.閉塞
oブロック実行wait()を待つ.o同期ブロック取得オブジェクトの同期が煩雑な場合、同期ロックは他のスレッドに占有される.o他のブロックはsleep()またはjoin()メソッドを実行する.死.
7.ThreadLocalとは?
ThreadLocalはスレッドのローカル変数を作成するために使用され、オブジェクトのすべてのスレッドがグローバル変数を共有することを知っています.したがって、これらの変数はスレッドが安全ではありません.同期技術を使用することができます.しかし、同期を使用したくない場合は、ThreadLocal変数を選択できます.
各スレッドには、get()set()メソッドを使用してデフォルト値を取得したり、スレッド内で値を変更したりする独自のThread変数があります.ThreadLocalインスタンスは、通常、スレッドステータスに関連付けられてprivate staticプロパティであることを望んでいます.
8.run()とstart()の違い.
run():通常のrunメソッドを呼び出すだけ
start():スレッドが開始され、Jvmによってrunメソッドが呼び出されます.
スレッドを開始するにはstart()メソッドを呼び出し、スレッドが表す仮想プロセッサを実行可能にします.これは、JVMによってスケジュールされ、実行できることを意味します.これは、スレッドがすぐに実行されるという意味ではありません.run()メソッドは、スレッドを停止するために終了しなければならないフラグを生成することができる.
9.あなたが知っているスレッドの同期方法を教えてください.
wait():スレッドを待機状態にし、持つオブジェクトのlockを解放します.sleep():実行中のスレッドをスリープ状態にする静的メソッドで、InterruptedException例外をキャプチャするために呼び出されます.notify():待機中のスレッドを起動します.このメソッドを呼び出すと、待機中のスレッドを正確に起動するのではなく、JVMによって起動するスレッドを決定し、優先度ではありません.notityAll():すべての待機状態にあるスレッドを起動します.すべての起動スレッドにオブジェクトのロックを与えるのではなく、競合させることに注意してください.
10.スレッドスケジューリングとスレッド制御.
スレッドのスケジュール(優先度):
スレッドのスリープと同様に、スレッドの優先度はスレッドの実行順序を保証できません.ただし,優先度の高いスレッドはCPUリソースを取得する確率が高く,優先度の低いスレッドは実行する機会がないわけではない.スレッドの優先度は1~10の整数で表され、数値が大きいほど優先度が高くなり、デフォルトの優先度は5です.1つのスレッドで別の新しいスレッドを開くと、新しいスレッドはそのスレッドのサブスレッドと呼ばれ、サブスレッドの初期優先度は親スレッドと同じです.
スレッド制御
sleep()/スレッドスリープjoin()/スレッド加入yield()/スレッド礼譲setDaemon()/スレッドガード
割り込みスレッド
stop()interrupt()(最初に選択)
11.スレッド飢え死にとは何ですか.ロックとは何ですか.
すべてのスレッドがブロックされている場合、または必要なリソースが無効であるため処理できない場合、非ブロックスレッドが存在しないため、リソースが使用可能になります.JavaAPIでスレッド・ロックが発生する可能性があります.
すべてのスレッドがシーケンスでObjectを実行する.wait(0)、パラメータが0のwaitメソッド.プログラムは、対応するオブジェクトにスレッド呼び出しObjectがあるまでライフロックを発行する.notify()またはObject.notifyAll(). すべてのスレッドが無限ループに詰まっている場合.
12.マルチスレッドのビジーサイクルは何ですか?
ビジーサイクルとは、プログラマがループでスレッドを待機させることであり、従来の方法wait()やsleep()やyield()のようにCPU制御を放棄し、ビジーサイクルはCPUを放棄することなく、空のループを実行します.この目的はCPUキャッシュを保持することである.
マルチコアシステムでは、スレッドが目が覚めるのを待っている間に別のカーネルで実行される可能性があります.これにより、キャッシュが再構築されます.キャッシュの再構築を回避し、再構築を待つ時間を減らすために使用できます.
13.volatile変数は何ですか.volatile変数とatomic変数の違いは何ですか?
volatileは修飾された変数の可視性を保証する.volatileはマルチスレッドにおける同じ変数の可視性を保証するだけであるため,スイッチング状態としての変数,すなわちBooleanタイプを修飾するための変数であることが多い.
volatileは、類似スイッチタイプの変数を修飾するために使用されることが多く、Atomicは、類似カウンタ関連の変数、他のマルチスレッド同時動作synchronizedキーワード修飾に使用されることが多い.
volatileには2つの機能があります.
この変数は複数のスレッドにコピーが存在せず,メモリから直接読み出す.このキーワードは、命令の再ソート最適化を禁止します.すなわち、volatile変数の付与操作の後にメモリバリア(生成されたアセンブリコード)があり、読み取り操作がメモリバリアの前に並べ替えられない.
14.volatileタイプ変数はどのような保証を提供しますか?非原子操作を原子操作に変えることができますか?
volatileはhappens-beforeの保証を提供し、1つのスレッドの修正が他のスレッドに表示されることを保証します.
Javaではlongとdoubleを除くすべての基本タイプの読み取りと付与は原子的な操作です.一方,64ビットのlongとdouble変数は,JVMによって2つの分離された32ビットとして動作するため,原子性を持たず,ワード引き裂き問題を生じる.しかし、longまたはdouble変数を定義すると、volatileキーワードを使用すると、(単純な付与と戻り操作の)原子性が得られます.