java-RMI和同步

戴夫·克拉克(Dave Clarke)

我目前正在用Java编写一个简单的聊天应用程序。它具有服务器应用程序和客户端应用程序,均使用Java编写并使用RMI进行通信。

在服务器上,有一个ArrayList活动用户,该用户在用户上线和脱机时都会更新。与服务器的每个客户端连接都有其自己的线程。

建立新连接(即加入新客户端)后,将创建一个新线程,并在该线程内对其ArrayList进行更新以反映新用户。同样,当连接ArrayList断开时会更新来反映断开连接。

显然,由于有很多客户端,因此将有很多并发访问权限ArrayList因此,我的问题是,是否应该ArrayList同步访问/更新此方法的任何方法

斯图尔特·马克斯

其他答案建议使用Collections.synchronizedList()

List<User> list = Collections.synchronizedList(new ArrayList<>());

可能有效,但是您必须格外小心。这样的列表仅对于直接在该列表上的单个方法调用是线程安全的。但是,许多操作涉及列表上的多个操作,例如遍历列表。例如,一个人可能会编写以下代码,以向聊天中的每个用户发送一条消息:

for (User u : list)
    u.sendMessage(msg);

如果在迭代过程中将用户添加到列表中或从列表中删除用户,则将失败并显示a ConcurrentModificationException发生这种情况是因为这种形式的for循环Iterator从列表中获取一个,然后通过hasNextandnext调用重复访问该列表可以在这些访问之间修改列表。如果列表被修改,则Iterator检测到该列表并引发异常。

在Java SE 8中,可以改写以下内容:

list.forEach(u -> u.sendMesage(msg));

这是安全的,因为列表的锁定在整个forEach通话过程中都会保持。

(另一个建议是使用aSet代替List。。由于其他原因,这可能是个好主意,但是它也遇到了与List相同的并发问题。)

解决此问题的最佳方法是创建自己的对象,该对象包含一个用户列表(或一组)和任何相关数据,并在用户容器和相关数据上定义一组特定的操作。然后,在容器对象的方法周围添加适当的同步。这不仅允许您列表或一组用户,还可以对其他数据进行线程安全更新。

最后,volatile如果在构造时初始化了列表字段,则在使对象对其他线程可见之前就没有必要了。用RMI术语来说,如果在导出对象之前完成了构造,那么您是安全的。最好将该字段设置final为在初始化后知道所有其他线程都可以看到初始化值,并且此后不能更改该值。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Java和同步链表

来自分类Dev

Java中的同步方法和同步块

来自分类Dev

Java中的同步和同步块

来自分类Dev

Java同步和对象锁定

来自分类Dev

对Java同步的理解和困惑

来自分类Dev

RMI java.rmi.NoSuchObjectException和严重并发使用的端口重用

来自分类Dev

每个调用和队列的Java RMI新对象

来自分类Dev

Java中的哈希表和同步

来自分类Dev

Java同步等待和通知方法

来自分类Dev

荒谬的Java多线程和MySQL同步

来自分类Dev

Java中的线程安全和代码同步

来自分类Dev

在WebView和Java之间同步Cookie

来自分类Dev

混淆的Java Threadpool和同步方法

来自分类Dev

Java易失性和同步

来自分类Dev

在Java(和SWT)中同步“前端”和“后端”

来自分类Dev

Java同步中条件变量和条件谓词之间的区别

来自分类常见问题

Java同步块进入和退出时的内存障碍

来自分类Dev

Java并发性问题-锁定和同步方法

来自分类Dev

Android Java处理程序,线程同步块(notifyall和Wait)

来自分类Dev

是什么导致Java中较长的旋转和同步时间?

来自分类Dev

Android(Java)和.NET DateTime之间的高精度时间同步?

来自分类Dev

从Java到Kotlin:同步和锁定/等待/通知模式

来自分类Dev

如何正确同步和重用Java中的ForkJoinPool?

来自分类Dev

Java Thread:对象具有同步方法和非同步方法

来自分类Dev

Java RMI异常错误

来自分类Dev

Java ArrayList / RMI

来自分类Dev

Java RMI线程系统

来自分类Dev

Java RMI Unmarshall异常

来自分类Dev

Java RMI线程系统