2016-04-29 14 views
0

私は同じ質問の別のボードを記入しようとしていませんが、私は約15の解決策を読んでおり、誰も全く同じ問題を抱えていません。同期スレッドがお互いをブロックしていない

private AgentModel agent; 
private UserModel user; 
private int type; 

public AgentThread(AgentModel agent, UserModel user, int type) { 
    this.agent = agent; 
    this.user = user; 
    this.type = type; 
} 

public void start() throws InterruptedException { 
    agent.setT(new Thread(this, agent.getID())); 
    agent.getT().start(); 
} 

、道下り少し:

public void run() { 
    while (!agent.getT().isInterrupted()) { 
     agent.nextOP(); 

     try { 
      if (agent.getOPS() > 0) { 
       agent.getT().sleep((long) (1000/agent.getOPS())); 
      } else { 
       agent.getT().sleep(1000); 
      } 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      agent.getT().interrupt(); 
     } 
     synchronized (user) { 
      agent.setState(agent.getT().getState().toString()); 
      // System.out.println("Operations Completed: " + 
      // (1+agent.getOPCompleted())); 
      if (type == 3) { 
       user.deposit(agent.getAmount(), Integer.valueOf(agent.getID())); 
      } 
      if (type == 4) { 
       user.withdraw(agent.getAmount(), Integer.valueOf(agent.getID())); 
      } 
     } 
    } 
} 

エージェントオブジェクトは、メソッドを開始AgentThreadに開始されたスレッドが含まれていますここで私が見ていたコードです。 AgentThreadオブジェクトは、エージェント、ユーザー、それぞれのクラスのインスタンスの両方を取り込みます。

私の問題は次のとおりです。ロックをUserModelクラス 'user'のインスタンスに設定します。スレッドは、エージェントの種類によっては入金または払い戻しを行うものとします。

agent.getT().getState()を実行すると、作成したAgentThreadのインスタンス数に関係なく、常にRUNNABLEが返されます。各AgentThreadには新しいエージェントと新しいスレッドが与えられますが、同じUserオブジェクトが与えられます。あたかもスレッドが互いにブロックしていないかのようです。

リスナーで検出された変更を出力でき、実行中のすべてのスレッドとそのユーザーインスタンスとのやりとりを反映しているため、同じユーザーインスタンスに影響を与えていることは知っています。

スレッドが開始されるたびに、スレッドは「無限ループ」に入り、ユーザーインスタンスには入金または出金が行われます。これらのアクションは、x秒ごとに実行されます。

+0

私たちには表示されていないコードがたくさんありますが、好奇心のために、そのスレッドが同期化されたブロックをどれだけ過ごすことが予想されますか?これはほんの数マイクロ秒です。 「AgentThreadを何回作成しても、どれくらいのインスタンスが作成されていますか?どのくらいの頻度で 'synchronized'ブロックに入っていますか?そして、あなたのプログラムはスレッドの状態をどのくらい頻繁に要求しますか?私が実際にここで得ようとしていることは、あなたがそれに気付く可能性があるロックのために非常に多くの競合があると思わなければならない理由は何でしょうか? –

+0

@james large私は一度に4つのインスタンスを実行していましたが、すべてブロックをかなり早く入力し、プログラムはスレッドごとにブロックごとに状態を問い合わせます – BKreger

+0

@mastovスレッドが状態をチェックしていないとブロックされた場合、 – BKreger

答えて

0

スレッドは、おそらく数百ミリ秒の間隔でdeposit()またはwithdraw()操作を実行するのに十分な時間だけユーザーオブジェクトをロックします。 deposit()やwithdraw()が高レイテンシの外部リソースに依存していない限り、おそらく数千マイクロ秒のコードで十分です。その結果、スレッドがUserオブジェクトをロックしている状態でシステムをキャッチする可能性は、おそらく100,000に1未満です。さらに、別のスレッドをブロックするには、deposit()またはwithdraw()操作を実行しようとする必要があります。あなたの可能性のあるパラメータが与えられれば、そのような衝突の可能性は100万分の1にも満たないでしょう。

0

Agent.getT()。getState()を実行すると、作成したAgentThreadのインスタンス数に関係なく、常にRUNNABLEが返されます。

右。これは、スレッド自体の内部からagent.getT().getState()を呼び出しているためです。スレッドは常にと表示され、RUNNABLEと表示されます。それがブロックされたり待ったりしているときは、見ていません。

スレッドは決して互いにブロックしていないようです。

いいえ、コードを読んでも、同じUserオブジェクトで作業している場合は、コードを確実にブロックしています。しかし、他のスレッドからagent.getT().getState()を呼び出すことは決してないので、BLOCKEDまたはWAITINGの状態を見ることができます。

スレッドを外部から見る方法の1つはturning on JMXで、jconsoleを使用します。スレッド・タブに行くと、ワーカー・スレッドで「合計ブロック数」と「合計待機時間」のカウントが増えることがわかります。

スレッドが開始されるたびに、ユーザーインスタンスがデポジットまたは引き出しを持つ「無限ループ」に入ります。これらのアクションは、x秒ごとに実行されます。

私はそれがあなたが期待していると思います。

関連する問題