关于在java中使用套接字开发服务器

时间:2011-06-29 20:51:28

标签: java multithreading

我在这里有两个课程:

public final class ServerMain
{

      static List<Table> s_AvailableGameTables = new Vector<Table>(); 
      static List<Table> s_OccupiedGameTables = new Vector<Table>(); 
      static List<ServerThread> s_PlayersOnServer = new Vector<ServerThread>();
...
}
class ServerThread extends Thread{
...}

ServerMain是服务器本身,它通过为刚刚连接到ServerThreads的每个用户分配新的ServerThread来管理ServerMain

我的问题很简单:

  1. 当我正在特定的ServerThread中运行并且我想访问serverMain上的一些静态列表并更新它们时我该如何做,如果我已经“离开”了ServerMain的区域在处于后台运行的特定线程中。 唯一的方法是将每个serverthread的引用保存到papa ServerMain吗?

  2. 也许它可能会导致一些问题,好像同时代码的两个区域可以更新同一个列表ServerMain本身和ServerThread现在知道谁是大老板?

  3. 一般问题:套接字编程是指UDP还是TCP?

  4. 我想听听一些好的建议。提前谢谢。

5 个答案:

答案 0 :(得分:1)

  1. 不,你可以像'普通'那样引用它。从某种意义上说,没有语法上的变化来实际引用来自不同线程而不是不同对象的东西。现在,您可能需要同步对它的访问权限,但我并不认为这会改变 您引用的内容。
  2. 同步列表(最好使用java.util.concurrent包)。确保表本身也是线程安全的。
  3. 套接字也不使用传输协议,但它可以是UDP,TCP或其他任何东西。为了澄清,您只能通过说您正在使用套接字来确定正在使用的传输协议;你必须指定你实际使用的协议。

答案 1 :(得分:1)

对于#1,您不需要实例来访问ServerMain的 static 成员,假设它们是可访问的(例如它们是public),您可以将它们作为{{1}访问它们}}

对于#2,是的,您需要考虑使用ServerMain.MyVar语句来防止多个线程同时写入列表,或者使用线程安全列表实现。

对于#3,术语“套接字编程”可以指UDP或TCP。您使用哪种插槽取决于您正在实施的应用程序类型。

答案 2 :(得分:1)

  1. 如果使用同步列表(即Vector,java.util.concurrent包中的一个列表,或者它更适合Collections.synchronizedList(list)),则可以正常访问。
  2. 向量已经“已同步”,但请注意,您必须手动同步事务(即synchronized (vector) { vector.add(..); vector.remove(..); })。默认情况下,它使用的同步基本上会阻止列表方法调用中断当前正在执行的用户定义的事务和当前正在执行的列表上的方法调用。我建议使用Collections.synchronizedList(list)而不是Vector,尽管他们都做同样的工作,真的。
  3. ServerSocket / Socket是TCP,DatagramSocket是UDP。

答案 3 :(得分:1)

1)这是其中一种可能性。通常,当您需要访问另一个对象方法时,最好的方法是保持引用(直接或间接)。然而,因为假设您只有一个ServerMain对象,您可以尝试声明静态方法或使用单例构造(私有构造函数,您只能访问返回共享对象的getInstance()静态方法)。 / p>

2)线程之间的访问同步是一个漫长的主题,并且已经写了许多关于它的书籍。最简单的方法是使用synchronized方法(或块)并在里面执行所有种族敏感命令。但要有把握,这可能是这些同步块后来成为你的主要瓶颈。当你有更多的练习时,学习java同步方法。

3)正如其他java所述,您只需打开一个侦听给定端口号中的协议的套接字。您可以决定是将其设置为UDP还是TCP。当然,请记住,使用UDP时,您收到的消息可能不完整,因此必须由您的代码处理。

答案 4 :(得分:0)

1)这将是一种方式,可能是一种首选方式,但不一定是唯一的方式。

此外,引用不需要由ServerThread拥有。由于ServerMain可能是一个单例,我发现在这样的情况下,给Singleton一个引用自身的静态变量是有意义的。然后,从任何ServerThread,你可以做

class ServerThread extends Thread
{
    public void someMethod()
    {
        ServerMain.serverMain.whatever();
    }
}

2)是的,导致问题。阅读Java Concurrency Trail,特别是有关同步的部分。这是一个过于宽泛的主题,在这里的答案中很容易涵盖。但是对于快速而肮脏的答案,请查看同步方法。如果您只是使处理此列表访问的方法同步,那么它将是安全的。当然,根据您的需要,锁定列表访问权限可能会从您的线程中获取任何性能提升。

3)它不一定必须,但它通常会这样做。 “TCP套接字”甚至比“UDP套接字”更可能,但两者都有效。如果您希望为整个延长的事务提供专用且可靠的连接,则应该使用TCP。 TCP保证收到数据并以特定顺序接收数据。