【发布时间】:2012-09-05 19:13:54
【问题描述】:
在我的客户端/服务器桌面应用程序上。我有这个问题,我应该如何使用我的模型正确编码我的 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 而导致处理N 个客户端请求的延迟。但是由于我必须遵守规则 concurrency 和 synchronization 以确保 Server.T1Service 不会对 N 个客户端请求的队列感到困惑。以下是问题:
- 根据Effective Java - Second Edition 中关于
Static Factory的第1 项,这是否可以让我创建一个对Persistence 包类中的方法的新类引用? -
List<Client>中的每个Client元素是否会形成并发问题,让 N 个客户端更新它们的message字段同时触发ClientObsver.update(),其中此观察者的引用对象只是父类。 由于内存问题,我避免创建多个 T1Service 实例。 - 如果我们要按照 Effective Java - Second Edition 的内容,我如何将我的持久性类转换为易于阅读、易于实例化并支持并发的方式?
【问题讨论】:
-
要清楚,T1Service.update() 方法中是否有状态正在修改?如果并发调用方法时类中没有状态发生变化,则不存在线程安全问题。
-
我预见到的并发问题是
T1Service.update()在 2 个或更多客户端更新时触发。我忘记添加有关List<E extends java.util.Observable>的信息包含java.io.Sockets。 E 是什么,它拥有 Socket、I/O 流以及最重要的来自java.io.ObjectInputStream.readObject()的java.lang.Object message。当java.io.ObjectInputStream.readObject()收到一个新对象时,会调用java.util.Observable.setChanged()和java.util.Observable.notifyObservers()。 -
这里的详细程度尚不清楚 - List 是 update() 方法的参数,还是服务类的字段?向我们展示示例方法签名和类定义会容易得多。
-
List是服务类中方法的返回类型。List<E>其中E是一个域。 -
我已经用 Server.ClientObserver.update() 方法中特别发现的可能并发问题/性能问题的详细信息部分更新了我的问题。
标签: java concurrency static-methods static-factory