通常、サーブレット開発者はサーブレット インスタンスとの関連で同期化を認識していますが、実際の作業を実行するのはスレッドです。多くのスレッドが同時に実行されることもあります。
各インスタンスは複数のスレッドで実行される可能性があるため、オブジェクトスコープ変数やその他の共有リソースでの同期化の問題を認識する必要があります。同期化とは、1 つのコードをシングルスレッドとして実行させることです。スレッド管理は、JMC を使用して、各 JVM に別々のスレッド パラメータを指定することによって制御します。
メモ スレッド管理は高度な操作であるため、本書では扱いません。詳細については、Java スレッド管理に関する市販の解説書を参照してください。 |
クラススコープ インスタンス変数の同時アクセスを防止するには多くの方法があります。以下はその例です。
synchronized
を doXxx
メソッドのシグネチャに含める (この方法はお勧めしません)
SingleThreadModel
インターフェイスを実装する
メソッド シグネチャで synchronized
キーワードを使用することで、メソッド全体へのアクセスを同期化できます。
...
public class TestCaller extends HttpServlet { int visitorCounter = 0; // コンセプトの説明のみを目的とした例なので、実際には実行しないでください。 public synchronized void doGet(HttpServletRequest servReq, HttpServletResponse servRes) throws IOException, ServletException { ...
メモ この例は、コンセプトについて説明するためのものです。この同期化テクニックは パフォーマンスを低下させるため、実際にはほとんど使用しません。 |
synchronized
されたブロックを使用して、オブジェクトスコープ変数へのアクセスを同期化することができます。
...
int thisCount; synchronized(this) { // visitorCount はオブジェクトスコープ変数です。 thisCount = visitorCounter++; } out.println("<p>You are visitor number " + thisCount); ...
この例では、同期化された
ブロック内のカウンタを増分し、それによってオブジェクトスコープ変数へのシングルスレッド アクセスを保証します。
SingleThreadModel
インターフェイスは JRun に一群のサーブレット インスタンスを作成して、それぞれのインスタンスについて同時スレッドが service
メソッドを実行しないように指示します。
...
public class testSync extends HttpServlet implements SingleThreadModel { ...
JRun は SingleThreadModel
を実装するサーブレットの複数のインスタンスを作成するため、オブジェクトスコープ インスタンス変数がすべてのインスタンスについて同じでなければならない場合、このテクニックは使用できません。たとえば、このテクニックをヒット カウンタには使用できません。しかし、オブジェクトスコープインスタンス変数を使用しないサーブレットの場合、またはオブジェクトスコープ インスタンス変数が異なってもよい場合 (例 : バッファ変数、データベース接続) には、SingleThreadModel
は効果的なテクニックです。
オブジェクトスコープ変数へのすべてのアクセスが同期化されたメソッドによって行われるようなアクセス方式を実装できます。
...
public class TestSync extends HttpServlet { int visitorCounter = 0; public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { incrementCount(); ... public synchronized void incrementCount() { visitorCount++; } public synchronized int getCount() { return visitorCount; } ...