1

私は次のスピンロックアプローチを使用しています。

while(!hasPerformedAction()){
    //wait for the user to perform the action
    //can add timer here too
}

setHasPerformedAction(false);

return getActionPerfomed();

これは基本的に、ユーザーがアクションを実行するのを待ってからそれを返します。現在、何かが続行する前にユーザーからの回答を要求しているため、入力が受信されるまで待機します。ただし、これが非効率的であるかどうか、しばらく待っている場合(つまり、30秒未満)、このアプリを実行しているPCの速度が低下するのではないかと考えていました。このアプローチを使用する他の選択肢、つまりロック、セマフォがある場合、構文は何ですか?

ありがとう、

アリー

4

5 に答える 5

9

実際、これは非効率的であるだけでなく、表示しているコードに「発生前」のエッジがないため、機能することさえ保証されていません。発生前エッジを作成するには、次のいずれかを実行する必要があります。

  1. 揮発性変数にアクセスする
  2. 共有リソースで同期する
  3. 同時utilsロックを使用します。

別のコメントで述べたように、最も簡単な解決策は、フラグが揮発性変数であることを確認し、ループで短いスリープをスローすることです。

ただし、最善の方法は、共有変数で同期/待機/通知することです。

あなたが読む必要がある方法は、待つことと通知することです。これらの使用方法の詳細については、この記事をお読みください。コードスニペットの例を以下に示します。

スレッド1

Object shared = new Object();
startThread2(shared);
synchronized (shared) {
  while (taskNotDone())
    shared.wait();
}

スレッド2

// shared was saved at the start of the thread
// do some stuff
markTaskAsDone();
synchronized (shared) {
  shared.notify();
}
于 2010-01-31T21:09:23.923 に答える
2

あなたが書いたものはビジーループと呼ばれ、決してしてはいけません。

あなたはそれを続けたいと思うかもしれませんが、少なくともループに忙しくないように少し眠ってください、それでもそれほど素晴らしいことではないでしょう:

while( !hasPerformedAction() ) {
    (sleep a bit here)
}

これを行う別の方法は、ブロックしているキューにユーザーアクションをエンキューすることです。次に、queue.takeを使用するだけで、キューの実装が問題を処理します。

また、別の方法は、コールバックを使用してユーザーアクションを通知することです。

于 2010-01-31T21:09:29.930 に答える
2

Javaチュートリアルには、Javaでの並行性に関する優れたレッスンがあります。

http://java.sun.com/docs/books/tutorial/essential/concurrency/

別のスレッドからUIを変更する場合は、次のことを忘れないでください。

SwingUtils.invokeLater(actionToInvoke);
于 2010-01-31T21:09:43.317 に答える
1

タグにがgui含まれているので、アクションはGUIで行われると想定します。

この種のことを行うための「推奨される」方法は、メインスレッドをスリープ状態にし(おそらくを使用してwait())、アクションが実行されると、メインスレッドへのGUIアクションをnotify()覚醒状態に戻すことです。

于 2010-01-31T21:07:13.943 に答える
1

そのためのいくつかのクラスがにありますjava.util.concurrent.locks。クラスを見てくださいLockSupport

よろしくマイク

于 2010-01-31T21:08:21.197 に答える