2

クライアント/サーバー デスクトップ アプリケーションで。すべての永続化リクエストが並行性をサポートできるように、モデルを使用して JDBC クラスを適切にコーディングする方法について、この問題があります。i.e., multiple models want to request update to its persistence counterpart simultaneously [without atmost delay].

シナリオはこのようになります。サーバー アプリケーションにあるクラスに従います。

永続パッケージ:

abstract class AbstractService {
  // other fields
  private final String tName, tId;
  private final String sqlStatement;
  public AbstractService(final String tName, final String tId) {
    this.tName = tName;
    this.tId = tId;
    this.sqlStatement = ""; // SELECT statement
  }
  // java.sql.Connection() createConnection()
  // methods
}
public class T1Service extends AbstractService {
  private final String sqlDMLStatements;
  public T1Service() {
    super("t1", "t1Id");
    this.sqlDMLStatements = ""; // other DML statements
  }      
  // methods having return types of List<E>, Object, Boolean, etc.
  // i.e., public List<E> listAll()
}

コミュニケーションクラス【クライアントクラス】

import java.net.*;
import java.io.*;
public class Client extends Observable{
  private Socket socket;
  private ObjectInputStream input;
  private ObjectOutputStream output;
  private Object message;
  // Constructor
  // Getters/Setters
  // Other methods like open or close input/output
  private class ReceiverRunnable implements Runnable
    @Override
    public void run() {
       while(running) { // if socket is still open and I/O stream are open/initialized
          try { message = input.readObject(); } 
          catch(Exception e) {}
          finally { setChanged(); notifyObservers(); }  
       } 
    }
  }
}

メインクラス [サーバークラス]

import java.net.*;
public class Server {
   private List<Client> clientList; // holds all active connections with the server
   private T1Service    t1Service
   private class ConnectionRunnable implements Runnable {
      @Override public void run() {
         while(running) { // serverSocket is open
           Client client = new Client(ServerSocket.accept(), /* other parameters */);
           client.addObserver(new ClientObserver(client));
           clientList.add(client);
         }
      } 
   }
   private class ClientObserver implements Observer {
      private Client client;
      // Constructor
      public void update(Observable o, Object arg) {
         // Check the contents of 'message' to determine what to reply
         // i.e., message.equals("Broadcast") {
         // synchronized(clientList) {
         //   for(Client element : clientList) {
         //     element.getOutput().writeObject(replyObject);
         //     element.getOutput()..flush();
         //   }
         // }
         // i.e., message.equals("T1") {
         // synchronized(t1Service) {
         //     client.getOutput().writeObject(t1.findAll());
         //     client.getOutput().flush();
         // }
      } 
   } 
}

これはクライアント/サーバー アプリケーションであるため、クライアントからの複数の要求が同時にサーバーに送られます。サーバーは、適切な応答を適切なクライアントに送信する要求を処理します。注: クライアントとサーバーの間で送信されるすべてのオブジェクトは、java.io.Serializable のインスタンスです。

この種のシナリオで のブロックを調べるとServer.ClientServer.update()、パフォーマンスの問題が発生する可能性があります。または、Intrinsic Locks. しかし、私はルールconcurrencyを守らなければならず、それが N クライアント要求のキューに混乱しないようsynchronizationにする必要があります。Server.T1Service質問は次のとおりです。

  1. に関するEffective Java - Second Editionの項目1によると、Static Factoryこれにより、Persistenceパッケージのクラス内のメソッドへの新しいクラス参照を作成できますか?
  2. Client内部の各要素List<Client>は、N 個のクライアントがmessageフィールドを同時に更新しClientObsver.update()、このオブザーバーの参照オブジェクトが親クラスの単一のインスタンスであるという同時実行の問題を形成します。メモリの問題から、T1Service の複数のインスタンスを作成することは避けていました。
  3. 『Effective Java - Second Edition』の内容を使用する場合、永続性クラスを読みやすく、インスタンス化しやすく、並行性をサポートできるように変換するにはどうすればよいでしょうか?
4

2 に答える 2

2

Akkaのアクターなど、アクターを確認することもできます。

アクターの基本的な考え方は、送信イベントを使用して同期をまったく回避することです。Akka は、1 つのアクターが 2 つのスレッドによって同時に呼び出されることが決してないことを保証します。したがって、グローバル変数で何かを行うアクターを定義し、単純にメッセージを送信することができます。

通常は魅力のように機能します:)

于 2012-09-05T19:17:24.917 に答える
1

[項目 1] Static Factory の理論は正しいですか?

はい、コンストラクターの代わりに静的ファクトリーを使用できます。通常、これは構築ロジックが複雑で、ファクトリ パターンを保証するためにさまざまなサブタイプ間で共有される場合です。さらに、ファクトリは、DI フレームワークの外部で依存性注入の手段を提供する場合があります。

変換された静的ファクトリ グローバル オブジェクトの同時実行の問題は解決されるでしょうか?

構築を同期する必要がある場合は、静的ファクトリがうまく機能synchronizedします。ファクトリ メソッドのメソッド宣言に追加するだけです。オブジェクト自体のメソッドを同期する必要がある場合、これは役に立ちません。

グローバルオブジェクトへの同時アクセスを処理し、各グローバルオブジェクトのメソッドへのリアルタイムアクセスが必要な場合、静的ファクトリに変換することをお勧めしますか?

上で答えたように、それはあなたが達成しようとしていることに依存します。コンストラクターの同期には、ファクトリを使用します。

于 2012-09-05T19:29:48.240 に答える