java多线程网站服务器,多线程Java服务器:允许一个线程访问另一个

class Server {

public void main() {

// ...

ServerSocket serverSocket = new ServerSocket(PORT);

while (true) {

Socket socket = serverSocket.accept();

Thread thread = new Thread(new Session(socket));

thread.start();

}

// ..

}

public static synchronized Session findByUser(String user) {

for (int i = 0; i < sessions.size(); i++) {

Session session = sessions.get(i);

if (session.getUserID().equals(user)) {

return session;

}

}

return null;

}

}

class Session {

public Session(Socket socket) {

attach(socket);

}

public void attach(Socket socket) {

// get socket's input and output streams

// start another thread to handle messaging (if not already started)

}

public void run() {

// ...

// user logs in and if he's got another session opened, attach to it

Session session = Server.findByUser(userId);

if (session != null) {

// close input and output streams

// ...

session.attach(socket);

return;

}

// ..

}

}

我在这里的问题是:是否安全发布在Server.findByUser方法会话引用,没有按它是否违反OOP风格等? 或者我应该通过一些不可变的id引用会话并封装整个事情?你还会在这里改变什么?

String sessionId = Server.findByUser(userId);

if (sessionId != null && sessionId.length() > 0) {

// close input and output streams

// ...

Server.attach(sessionId, socket);

return;

}

托马斯:

谢谢您的回答。

我同意,在现实世界,这将是创造Session一个新的实例时使用依赖注入是一个好主意,但随后可能还与接口,右侧(下面的代码)?尽管我可能应该为此进行单元测试,但让我们考虑一下。然后我需要一个Server实例。 那么使用静态方法而不是单数的方式会是一个巨大的OO犯罪吗?

interface Server {

Session findByUser(String user);

}

class ServerImpl implements Server {

public Session findByUser(String user) { }

}

class Session {

public Session(Server server, Socket socket) { }

}

在attach(...)方法好一点 - 我从来没有考虑子类Session类,这可能就是我还没有想过如何risy它可能是调用构造函数公共方法。但是,我实际上需要一些公共方法来将会话附加到不同的套接字,所以也许有一对方法?

class Session {

public Session(Socket socket) {

attach_socket(socket);

}

public void attach(Socket socket) {

attach_socket(socket);

}

private void attach_socket(Socket socket) {

// ...

}

}

这是真的,会议允许客户端调用attach(...)看起来不正确。这可能只是服务器应该访问的那些严重的方法之一。但是如果没有C++的友谊关系,我该怎么做?不知何故,内心课程出现在我的脑海里,但我没有多少考虑,所以这可能是一个完全错误的路径。

每次我收到一个新的连接,我产生一个新的线程(并创建一个新的与它关联的会话实例)来处理传输。这样,当用户发送登录命令时,服务器已准备好接受新的连接。一旦用户的身份通过验证,我会检查他是否有机会登录(还有另一个正在进行的会话)。如果他是我从它的套接字分离onging会话,关闭该套接字,将正在进行的会话连接到当前套接字并关闭当前会话。希望这更清楚地解释实际发生了什么?也许使用会话在这里有点不幸。我真正拥有的是为每个连接(和3个线程)创建的4个不同对象:套接字处理程序,消息发送者,消息接收者和会话(如果这是一个很好的解决方案,这是一个不同的问题......)。我只是简单地尝试了源代码来关注这个问题。

我完全同意,当你可以使用地图时迭代会话列表是没有意义的。但是恐怕这可能是我正在处理的代码中的一个小问题(相信我)。我应该提到它实际上是一些遗留系统,毫不奇怪,最近有人发现它有一些并发性和性能问题。我的任务是修复它......当你几乎只有多线程的理论知识或仅仅用它来显示进度条时,这不是一件容易的事情。

如果在此之后,相当冗长,澄清你对这个架构有更多的了解,我会乐于倾听。

2009-11-27

lukem00

+1

static:使用static可以确定(在一个类中)可以“实例化”多少个“实例”:一个。这确实限制了课程的可用性。 (例如,您不能听另一个套接字。)测试会话实际上是不可能的。 (你不能创建服务器模拟。)这是DI(和服务定位器)的动机。 –

2009-11-27 14:25:08

+0

attach(...):你可以把它封装成private:public void attach(Socket socket) - > void attach(Socket socket)。但我仍然认为责任应该放入服务器。 –

2009-11-27 14:26:05

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值