Tag: 同步

Java发生在之前和同步

我对Java的发生和同步有一些分歧。 想象一下以下场景: 主线程 MyObject o = new MyObject(); // (0) synchronized (sharedMonitor) { // (1) add the object to a shared collection } // (2) spawn other threads 其他主题 MyObject o; synchronized (sharedMonitor) { // (3) retrieve the previously added object } // (4) actions to modify the object 请注意, MyObject的实例变量既不是volatile ,也不是final 。 MyObject的方法不使用同步。 我的理解是: […]

将synchronized()与ReentrantLock.lock()混合

在Java中, ReentrantLock.lock()和ReetrantLock.unlock()使用与ReetrantLock.unlock()相同的锁定机制? 我的猜测是“不”,但我希望是错的。 例: 想象一下,线程1和线程2都可以访问: ReentrantLock lock = new ReentrantLock(); 线程1运行: synchronized (lock) { // blah } 线程2运行: lock.lock(); try { // blah } finally { lock.unlock(); } 假设线程1首先到达其部分,然后在线程1完成之前到达线程2:线程2将等待线程1离开synchronized()块,还是继续运行?

同步客户端 – 服务器游戏状态

我正在制作一个客户端服务器MMO风格的游戏。 到目前为止,我已经设置了框架,以便服务器和客户端相互交互以提供状态更新。 服务器维护游戏状态并定期计算下一个状态,然后每隔一段时间(每n毫秒)将其发送给所有客户端。 用户可以在客户端查看和响应该新状态。 然后将这些操作发送回服务器进行处理并发送出去进行下一次更新。 显而易见的问题是这些更新需要时间在服务器和客户端之间传输。 如果客户端行动攻击敌人,那么当更新回到服务器时,服务器很可能已经使游戏状态进展得足够远,以至于敌人不再在同一地点,并且超出范围。 为了解决这个问题,我一直试图找到一个好的解决方案。 我看了下面的内容,它帮助了一些,但并不完全: Mutli Player Game同步 。 我已经得出结论,我不仅可以传输游戏的当前状态,而且可以传输其他信息,例如方向(或AI运动的目标位置)和速度。 从这一点来看,我有一部分需要在客户端“猜测”实际状态是什么(如服务器所见),通过将游戏状态推进到未来n毫秒。 问题是确定进展状态的时间量,因为它将取决于服务器和客户端之间的滞后时间,这可能会有很大差异。 此外,我应该将游戏状态推进到客户端查看时的状态(即仅考虑更新到达客户端所花费的时间),还是应该将其推进到足够远以便在发送响应时回到服务器,到那时它将是正确的状态(来往于旅程的帐户)。 有什么建议么? 重申: 1)计算发送和接收之间的时间量的最佳方法是什么? 2)我是否应该将客户端状态推进到足以计入整个往返时间,或者只是将数据从服务器提供给客户端所需的时间? 编辑:到目前为止我想出了什么 由于我已经有许多数据包在客户端和服务器之间来回传递,我不想在必要时添加到该流量。 目前,客户端向服务器发送状态更新数据包(UDP)〜150毫秒(仅在某些内容发生变化时),然后由服务器接收和处理这些数据包。 目前,服务器不会对这些数据包发送任何响应。 首先,我将让客户尝试估计他们的滞后时间。 我将它默认为50至100毫秒。 我建议大约每2秒(每个客户端)服务器将立即响应其中一个数据包,在特殊的定时更新数据包中发回数据包索引。 如果客户端收到定时数据包,它将使用索引来计算此数据包发送的时间,然后使用数据包之间的时间作为新的延迟时间。 这应该使客户合理地保持最新的延迟,同时避免过多的网络流量。 声音可以接受,还是有更好的方法? 这仍然没有回答问题二。

最终字段对于线程安全是否真的有用?

我已经每天使用Java Memory Model工作多年了。 我认为我对数据竞争的概念以及避免它们的不同方法(例如,同步块,易变变量等)有很好的理解。 但是,我仍然认为我完全不了解内存模型,这是最终的类字段在没有任何进一步同步的情况下应该是线程安全的方式。 所以根据规范,如果一个对象被正确初始化(也就是说,没有引用对象在其构造函数中以某种方式转义,使得引用可以被另一个线程看到),那么,在构造之后,任何看到该对象的线程对象将保证看到对象的所有最终字段的引用(在它们构造时的状态),没有任何进一步的同步。 特别是,标准( http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4 )说: final字段的用法模型很简单:在该对象的构造函数中设置对象的最终字段; 并且在对象的构造函数完成之前,不要在另一个线程可以看到的地方写入对正在构造的对象的引用。 如果遵循此操作,那么当另一个线程看到该对象时,该线程将始终看到该对象的最终字段的正确构造版本。 它还将看到那些最终字段引用的任何对象或数组的版本,这些字段至少与最终字段一样是最新的。 他们甚至给出了以下示例: class FinalFieldExample { final int x; int y; static FinalFieldExample f; public FinalFieldExample() { x = 3; y = 4; } static void writer() { f = new FinalFieldExample(); } static void reader() { if (f != null) { int i […]

Java RMI和同步方法

我正在研究“分布式系统”一书(由Tanenbaum和Van Steen撰写),他们说的东西似乎与许多人在Java RMI和同步方法上的想法相冲突。 我认为在远程对象实现上使用synchronized方法 (因此在服务器上运行的实际实现)即使对该方法的调用来自不同的客户端机器(通过代理调用该方法),也会阻止该方法的并发执行……又名Stub)。 我已经看到很多人都有相同的看法,例如在这里看看: Java RMI和线程同步问题 在本书中,它表示使用RMI时不会阻止同步方法的并发执行。 这是本书的相关摘录(您只能阅读粗体句子,但如果您愿意,可以阅读上下文): 逻辑上,远程对象中的阻塞很简单。 假设客户端A调用远程对象的同步方法。 要使对远程对象的访问看起来与本地对象完全相同,有必要在实现对象接口的客户端存根中阻止A,并且A有直接访问权限。 同样,在将其请求发送到服务器之前,还需要在本地阻止另一台机器上的另一个客户端。 结果是我们需要在不同的机器上同步不同的客户端。 正如我们在Chap中讨论的那样。 6,分布式同步可能相当复杂。 另一种方法是仅允许在服务器上进行阻止。 原则上,这样可以正常工作,但是当客户端在服务器处理其调用时崩溃时会出现问题。 正如我们在Chap中讨论的那样。 8,我们可能需要相对复杂的协议来处理这种情况,这可能会显着影响远程方法调用的整体性能。 因此,Java RMI的设计者选择仅限制对代理的远程对象的阻塞(Wollrath等,1996)。 这意味着将阻止同一进程中的线程同时访问同一个远程对象,但不同进程中的线程不会。 显然,这些同步语义很棘手:在语法层面(即,在阅读源代码时),我们可能会看到一个漂亮,干净的设计。 只有在实际执行分布式应用程序时,才能观察到应该在设计时处理的意外行为。 […] 我认为文章“Java系统的分布式对象模型”( 可在此处获得 )在文本中引用了Wollrath et all, 1996括号内。 然而,我在该论文中找到的唯一相关段落就是这一段: 由于本地和远程对象的故障模式不同,分布式等待和通知要求所涉及的实体之间的协议更复杂(例如,客户端崩溃不会导致远程对象永久锁定),因此,不能轻易地适应Java中的本地线程模型。 因此,客户端可以在远程引用上使用notify和wait方法,但该客户端必须知道此类操作不涉及实际的远程对象,只涉及远程对象的本地代理(存根)。 我是以错误的方式解释文本还是事实上说使用RMI时同步方法“不是那么同步”?

在两台服务器之间同步缓存数据的最佳方法

想要在两个服务器之间同步缓存数据。 两个数据库共享同一个数据库,但为了更好的执行数据,我在启动时将数据缓存到Hash Map中。 因此,希望在不重新启动服务器的情况下同步缓存的数据。 (两台服务器同时启动)。 请建议我最好和最有效的方法。

如何确保已重写的方法已同步

我有一类线程安全的公共代码。 该类中的一个方法是抽象的,需要为不同的实现重写。 我需要确保或至少向其他开发人员标记此方法的所有实现都需要是线程安全的。 做这个的最好方式是什么? 这个效果有关键字或注释吗? 我已经尝试过abstract synchronized但不允许使用关键字组合。

在重入锁定的条件下等待

以下代码取自Condition的JavaDoc : class BoundedBuffer { final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws InterruptedException { lock.lock(); try { while (count == items.length) notFull.await(); items[putptr] = x; if (++putptr == items.length) putptr = […]

同步异步任务的最佳方法

我的问题:我已经将802.15.4无线网络连接到串口(使用包装器)。 我可以将包发送到网络并监听传入的包。 你可以想象这是高度异步的。 执行任务:我想向网络发送命令并在一个函数调用中等待响应。 例如:我想从节点获取网络ID为1338的温度。 double getTemperature(int id) throws Exception { …. } 除了执行所有这些“同步(对象)等待(…)通知(..)”之外​​,还有更好的方法来等待响应消息吗? 最好的问候,bigbohne 也许添加一些香料: 这应该都以Web界面结束,用户可以通过ajax或直接请求这些命令。 我还想过在数据库中缓存响应值。 但是对于某些命令,你MUSS可以直接回答成功/失败

primefaces操作和multithreading

最近我正在阅读一个教程,因为我遇到了一个声明说… “Java语言规范保证读取或写入变量是一个primefaces操作(除非变量是long或double类型)。类型为long或double操作变量只有在使用volatile关键字声明时才是primefaces的。” AtomicInteger或AtomicLong提供像getAndDecrement() , getAndIncrement()和getAndSet()这样的方法。 我对上述陈述感到困惑。你能否澄清何时使用 AtomicInteger或AtomicLong类。