0

jconsole/Visual VM 経由でアクセスできるサービスがあります。

@ManagedResource
public class MyService
{
  private String foo;

  @ManagedAttribute
  public void setFoo(String newVal) { this.foo = newVal; }

  @ManagedAttribute
  public String getFoo() { return this.foo; }

  //some other things here that access foo
}

しかしfoo、Web アプリ コントローラーが受け取る値は、jconsle またはビジュアル VM で getFoo() をクリックしたときに取得する値と常に一致するとは限りません。また、デバッガーは、コントローラーが取得する値が jconsole に表示されるものではないことを示しています。

何か案が?

4

1 に答える 1

2

しかし、Web アプリ コントローラーによって受信された foo の値は、j​​consle またはビジュアル VM で getFoo() をクリックしたときに取得した値と常に一致するとは限りません。また、デバッガーは、コントローラーが取得する値が jconsole に表示されるものではないことを示しています。

よくわかりませんがfoo、さまざまなスレッド間で値が適切にメモリ同期されていないと思われます。値を表示しているスレッドとは別のスレッドによって更新されている場合は、fooそうする必要があります。または、JMX が古くなっていることに我慢してください。volatile

private volatile String foo;

確かに、JMX 要求は、Web アプリが処理される別のスレッドから行われています。ただし、デバッガーには問題はなかったと思います。

編集:

MyService何度かやり取りした後、クラスの 2 つのインスタンスが作成/使用されている可能性があるかどうかを尋ねました。@abcXYZSystem.out.println("getting foo in " + System.identityHashCode(this) + " = " + foo);のようなものを getter および setter メソッドに追加すると、何らかの理由でクラスの 2 つの異なるインスタンスが実際に存在することが示されました。そのため、JMX スレッドは一方を参照し、Web アプリは他方を使用していました。ああ。

于 2013-09-18T21:50:38.070 に答える