スレッドセーフなコードを記述するためには、状態アクセス操作、特に共有状態や変更可能な状態へのアクセスを管理することが中心となります。複数のスレッドが状態変数にアクセスし、1 つのスレッドが書き込み操作を実行する場合、同期メカニズムを使用して、これらのスレッドの変数へのアクセスを調整する必要があります。ステートレス オブジェクトはスレッドセーフである必要があります。
#ステートレス オブジェクトにステートを追加するとどうなるでしょうか?
次の方法でリクエストの数を管理するために、サーブレットに「ヒット カウンター」を追加するとします。サーブレットにlong 型フィールドを追加し、リクエストが発生するたびにこの値に 1 を加えます。処理されます。public class UnsafeCountingFactorizer implements Servlet { private long count = 0; public long getCount() { return count ; } @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { // do something count++; } }
初期化の遅延は、一般的な状況です。競合状態:
public class LazyInitRace { private SomeObject instance = null; public SomeObject getInstance() { if(instance == null) instance = new SomeObject(); return instance ; } }
UnsafeCountingFactorizer の例では、スレッドが安全でない理由は、カウントがアトミックな操作ではないためです。アトミック クラスを使用すると、加算操作がアトミックであることを確認できます。
##
public class CountingFactorizer implements Servlet { private final AtomicLong count = new AtomicLong(0); public long getCount() { return count .get() ; } @Override public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException { // do something count.incrementAndGet(); } }
関連する学習の推奨事項:
Java 基本チュートリアル以上がJava のどのクラスがスレッドセーフですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。