可能性のある複製:
Java同期
私は本を読んでいますBeginning Android Games。
synchronized()
を多く使用しますが、それが何をするのか本当に理解していません。私は長い間Javaを使用していないので、マルチスレッドを使用したことがあるかどうかわかりません。
Canvasの例では、synchronized(this)
を使用しています。ただし、OpenGL ESの例では、stateChanged
というオブジェクトを作成し、synchronized(stateChanged)
を使用します。ゲームの状態が変化すると、stateChanged.wait()
を呼び出してからstateChanged.notifyAll();
を呼び出します
いくつかのコード:
Object stateChanged = new Object();
//The onPause() looks like this:
public void onPause()
{
synchronized(stateChanged)
{
if(isFinishing())
state = GLGameState.Finished;
else
state = GLGameState.Paused;
while(true)
{
try
{
stateChanged.wait();
break;
} catch(InterruptedException e)
{
}
}
}
}
//The onDrawSurface looks like this:
public void onDrawFrame(GL10 gl)
{
GLGameState state = null;
synchronized(stateChanged)
{
state = this.state;
}
if(state == GLGameState.Running)
{
}
if(state == GLGameState.Paused)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
if(state == GLGameState.Finished)
{
synchronized(stateChanged)
{
this.state = GLGameState.Idle;
stateChanged.notifyAll();
}
}
}
//the onResume() looks like this:
synchronized(stateChanged)
{
state = GLGameState.Running;
startTime = System.nanoTime();
}
このJavaチュートリアル は、おそらくオブジェクトでsynchronizedを使用すると何が起こるかを理解するのに役立ちます。
object.wait()
が呼び出されると、そのオブジェクトに保持されているロックが解除され(synchronized(object)
と言ったときに発生します)、スレッドがフリーズします。スレッドは、別のスレッドによってobject.notify()
またはobject.notifyAll()
が呼び出されるまで待機します。これらの呼び出しのいずれかが発生すると、object.wait()
が原因で停止されたすべてのスレッドが続行できるようになります。これは、notは、object.notify()
またはobject.notifyAll()
を呼び出したスレッドがフリーズし、制御を待機中に渡すことを意味しますスレッド、それは単に、これらの待機スレッドが継続できることを意味しますが、以前は継続できませんでした。
synchronized
キーワードは、変数またはメソッドをスレッドセーフに保つために使用されます。同期ブロックで変数を次のようにラップする場合:
synchronized(myVar) {
// Logic involing myVar
}
次に、同期ブロック内のロジックの実行中に別のスレッドからmyVarの値を変更しようとすると、ブロックの実行が完了するまで待機します。これにより、ブロックに入るライフサイクル全体を通じて同じ値になることが保証されます。
このように使用する場合:
private synchronized void someMehtod()
次の効果が得られます。
1。最初に、同じオブジェクトで同期メソッドを2回呼び出してインターリーブすることはできません。 1つのスレッドがオブジェクトの同期メソッドを実行している場合、同じオブジェクトの同期メソッドを呼び出す他のすべてのスレッドは、オブジェクトで最初のスレッドが完了するまでブロック(実行を中断)します。
2。次に、同期メソッドが終了すると、同じオブジェクトに対する同期メソッドの以降の呼び出しと発生前の関係を自動的に確立します。これにより、オブジェクトの状態の変更がすべてのスレッドに表示されることが保証されます。
( here から取得)
コードの同期ブロックを使用すると、同様の効果が得られます。
private void someMethod() {
// some actions...
synchronized(this) {
// code here has synchronized access
}
// more actions...
}
説明通り こちら
Java(Androidに基づいています)は、複数のCPUコアを利用できる複数のスレッドで実行できます。マルチスレッドとは、2つのプロセスをJava一度に1つのスレッドのみが操作できるようにする必要があるコードブロックまたはメソッドがある場合、そのコードブロックを同期します。
同期の使用にはプロセッサ/ IOのコストがかかり、必要な場合にのみ使用することを知っておくことが重要です。また、Javaクラス/メソッドがスレッドセーフであるかを調査することも重要です。たとえば、++インクリメント演算子はスレッドセーフであると保証されていませんが、同期コードのブロックを簡単に作成できます+ = 1を使用して値をインクリメントします。
アクティブにできるスレッドは1つだけであり、指定されたオブジェクトによってブロック内で同期されます。 waitの呼び出しはこの権利を放棄し、誰かがnotify(all)()を呼び出すまで現在のスレッドを非アクティブ化します。その後、非アクティブなスレッドは同期ブロックで再度実行したいが、それを必要とする他のすべてのスレッドと同等に扱われます。実際にそこに到達するのは、何らかの形で選択された1つだけです(プログラマーはどちらに影響を与えることも依存することもできません)。
Javaの同期キーワードは、2つの目的に使用されます。
最初の意味は、いわゆるクリティカルセクション、つまり、1つのスレッドが同時にアクセスできるコードの一部です。 synchronized
に渡すオブジェクトは、ある種の命名を許可します。1つのコードがsynchronized(a)
で実行された場合、synchronized(a)
にある他のブロックにはアクセスできませんが、 synchronized(b)
にコード化します。
その他の問題は、スレッド間通信です。スレッドは、他のスレッドが通知するまで待機できます。待機と通知の両方をsynchronized
ブロックに書き込む必要があります。
非常に短い説明でした。マルチスレッドに関するチュートリアルを検索して読むことをお勧めします。
キーワードsynchronizedは、待機操作および通知操作とともに 非ブロッキング条件モニター を形成します。これは、複数のスレッドを調整するのに便利な構成です。