1. ホーム
  2. java

[解決済み] Javaでブロックされないようにオブジェクトがロック(同期)されているかどうかを判断するにはどうすればよいですか?

2023-05-29 16:10:29

質問

私はレコードのセット(レコードA、レコードB、など...)を持つメモリ内のテーブルを含むプロセスAを持っています。

さて、このプロセスは、レコードに影響を与える多くのスレッドを起動することができ、時には我々は同じレコードにアクセスしようとする2つのスレッドを持つことができます - この状況は拒否する必要があります。具体的には、レコードが1つのスレッドによってロックされた場合、私は他のスレッドを中止したい(私はBLOCKまたはWAITを望んでいない)。

現在、私はこのようなことを行っています。

synchronized(record)
{
performOperation(record);
}

しかし、これでは問題が発生します。Process1が処理を実行している間、Process2が来ると同期されたステートメントでブロック/待機し、Process1が終了すると処理が実行されるからです。代わりに、私はこのようなものが欲しいのです。

if (record is locked)
   return;

synchronized(record)
{
performOperation(record);
}

これを実現するための手がかりがあれば教えてください。 何かヒントがあれば、ぜひ教えてください。 ありがとうございます。

どのように解決するのですか?

一つ注意すべきは インスタント というのは、そのような情報を受け取った時点で、その情報は古くなってしまうからです。言い換えると、誰もロックしていないと言われたのに、それを取得しようとすると、チェックしてから取得しようとするまでの間に別のスレッドがロックを取り出したためブロックされる可能性があります。

Brian が指摘するとおり Lock を指すのは正しいのですが、あなたが本当に欲しいのはその tryLock メソッドです。

Lock lock = new ReentrantLock();
......
if (lock.tryLock())
{
    // Got the lock
    try
    {
        // Process record
    }
    finally
    {
        // Make sure to unlock so that we don't cause a deadlock
        lock.unlock();
    }
}
else
{
    // Someone else had the lock, abort
}

を呼び出すこともできます。 tryLock を、待ち時間を指定して呼び出すこともできます。つまり、10分の1秒だけ取得を試みて、取得できなかったら中止するというようなことができます(例)。

(私が知る限り、Java API が "built-in" ロックに対して Monitor クラスが.NETでそうであるように。そしてまた、スレッドに関して言えば、私が両プラットフォームで嫌いな他の多くのことがあります - たとえば、すべてのオブジェクトが潜在的にモニターを持つことです!)