2

時々ルーターにログインして変更を加える必要があるプロジェクトがあります。Eclipseでは、変更が必要なすべてのものを処理する別のプロジェクトがあり、マルチスレッドプロジェクトであるメインプロジェクトのビルドパスにあります。私の問題は、時々 2 つのスレッドがルーターにアクセスしようとして、物事が台無しになることです。1 つのスレッドだけがコードの特定の部分にアクセスできるようにするためにできることはありますか?

これは、メインのマルチスレッド アプリケーションの関連コードです。

if (totalLogins > 10)
{
  IpManager.rebootRouter();
  Thread.sleep(4000);
  totalLogins = 0;
  composedMessagesWithThisIP = 0;
}

そして、他のプロジェクトでは、これは私が持っているものです

public synchronized static void rebootRouter()
{
  try
  {
    //code related to restart modem
  }
  catch (Exception e)
  {

  }
}

そのため、メソッドを同期させましたが、時々複数のスレッドが「rebootRouter」メソッドにアクセスすると思います。これは私のメインアプリケーションで問題を引き起こします。

IpManager.rebootRouter() を 1 つのスレッドのみで実行するための最良の方法と最も効果的な方法は何ですか?

よろしく!

4

4 に答える 4

1

synchronized一度に 1 つのスレッドのみがブロックに入ることができることを保証しますが、同じスレッドが複数回ブロックに入ることができるように (スレッドが自分自身に対してデッドロックしないようにするため)、別のスレッドがそこにあるためにスレッドがブロックされている場合は、最初のスレッドが同期ブロックを離れた直後に実行されます。

まず、ルーチンの入口と出口でロギングをスローします。再帰が行われていないことを確認し、呼び出しが実際に同時に実行されていることを確認します。また、非同期作業またはコールバックがある場合、同期ブロックが終了する可能性があることに注意してください。

于 2012-07-11T06:56:01.113 に答える
1

からセマフォを使用して、オブジェクトにアクセスするスレッドの数java.util.concurrent package制限します。

例:

このコード スニペットでは、一度に 1 つのスレッドのみがオブジェクトにアクセスできます。

Semaphore s = new Semaphore(1);  

s.acquire();

synchronized(this){

// Your modem work

}

s.release();
于 2012-07-11T07:01:34.873 に答える
0

So what I have done is made the method synchronized but I believe from time to time more than one thread access the "rebootRouter" method.

synchronized複数のスレッドがこのメソッドを同時に実行できないことを保証するため、このメソッドをマークしました。コード内に 問題を引き起こす可能性// Your modem workのあるものが含まれている可能性があります。unsynchronized

于 2012-07-11T07:08:58.630 に答える
0

私の問題は、時々 2 つのスレッドがルーターにアクセスしようとして、物事が台無しになることです。1 つのスレッドだけがコードの特定の部分にアクセスできるようにするためにできることはありますか?

「物事を台無しにする」を定義します。は同期されているためrebootRouter、特定の時点でそのメソッドを実行できるスレッドは 1 つだけです。しかし、あるスレッド (スレッド A と呼びます) が別のスレッド (スレッド B) によって実行されている間にそれを呼び出そうとすると、スレッド A は B が から戻るまでブロックされrebootRouter、その後 A は自分自身を直接呼び出しrebootRouterます。これがあなたが望む動作である場合、問題は別の場所にあります (synchronizedが壊れていないか、誰かが気づいているでしょう)。

rebootRouter上記の例のスレッド Aが別のスレッドによって呼び出された場合に、上記の例のスレッド A が呼び出されないようにするには、次を使用できますLock.tryLock

private static final Lock lock = new ReentrantLock();
public static void rebootRouter() {
  if (!lock.tryLock()) return;
  try {
    //code related to restart modem
  } catch (Exception e) {
    // Note: Empty catch blocks considered bad style
  } finally {
    lock.unlock();
  }
}

ニーズがより具体的である場合は、おそらく質問を言い換える必要があります。

于 2012-07-11T07:42:17.973 に答える