当前位置: 首页 > 知识库问答 >
问题:

线程间同步对象的最佳实践

和和裕
2023-03-14

我基本上有一个对象,它存储了一个项目的3D位置和其他属性,如速度。该位置每隔100毫秒由一个单独的威胁计算一次。另一种威胁访问这些属性并修改其中的一些属性。

// ...
double z = location.getZ();
// calculate new position
location.setZ(z);
// ...
// ...
while(location.getZ() > 10); // Some busy waiting for demonstration
location.setSpeed(10);
// ...

我的第一个想法是简单地对每个属性使用volatile,但据我所知,对volatile属性的每个操作都必须是原子的。由于这两种威胁都允许在某些情况下改变某些属性(如速度),这似乎不起作用。

我的下一个想法是使用Java的synchronized关键字,同步每个getter和setter,结束整个模拟周期。

// Location.java
public synchronized double getZ() { /* ... */ }

// Simulation loop
synchronized(location) {
    // calculations are done here
}

现在我想知道这是什么地方是正确的方法,或者是否有更好的方法。

synchronized块内部调用getz()可以吗?还是在内部调用这个结果我需要一个单独的锁吗?

共有1个答案

韩明德
2023-03-14

您使用synchronized的方法看起来是正确的。Volatile确保与同一变量的下一次读取存在happens-before关系。但它并不能建立原子性。

您可以使用synchronize关键字来确保这两者都发生-之前&原子性正常工作。只要确保您锁定的是getter和setter方法中的同一个监视器对象。

Getter方法也需要同步。否则,在属性未建立之前,getter方法可以从本地CPU缓存读取变量值&而不是从主内存读取变量值。所以其他线程可能已经使用同步的setter更新了主内存中的值,但是getter仍然在从CPU缓存读取过时的缓存值。

 类似资料:
  • 现在我的问题是:关键字对这种情况有用吗?

  • 在多线程实时系统中,一项工作的完成往往可以通过多个线程协调的方式共同来完成,那么多个线程之间如何 “默契” 协作才能使这项工作无差错执行?下面举个例子说明。 例如一项工作中的两个线程:一个线程从传感器中接收数据并且将数据写到共享内存中,同时另一个线程周期性的从共享内存中读取数据并发送去显示,下图描述了两个线程间的数据传递: 如果对共享内存的访问不是排他性的,那么各个线程间可能同时访问它,这将引起数

  • 我已经面临这个问题很多天了,请帮我解决。我正在使用线程同步实现生产者-消费者示例。我在这个传统节目中做了一些调整。我没有只使用一个队列对象,而是使用了两个队列对象。但程序不起作用。。(PS-我知道我可以通过只使用队列的一个对象来让这个程序工作,但如果我想使用两个队列对象呢??) 类队列{ } 类生产者实现Runnable{ } 类消费者实现可运行{ } 公共类测试队列{ }

  • 3. 线程间同步 3.1. mutex 多个线程同时访问共享数据时可能会冲突,这跟前面讲信号时所说的可重入性是同样的问题。比如两个线程都要把某个全局变量增加1,这个操作在某平台需要三条指令完成: 从内存读变量值到寄存器 寄存器的值加1 将寄存器的值写回内存 假设两个线程在多处理器平台上同时执行这三条指令,则可能导致下图所示的结果,最后变量只加了一次而非两次。 图 35.1. 并行访问冲突 思考一下

  • 问题内容: 我最近写了我的第一个Android应用程序,大约有8,000-10,000行代码。一直阻碍我使用常规设计模式的一件事是android对异步调用(打开对话框,活动等)的大量使用。因此,我的代码很快就开始看起来像“意大利面”,而我最终开始不喜欢某些类。 是否有适用于任何人都会推荐的系统的特定设计模式或编程方法?对于编写可管理的异步代码有什么建议吗? 问题答案: 使用全局变量 如果您不想用简

  • 问题内容: 我在Java线程方面有一些经验,但我想知道… 存储多个线程的最佳实践是什么,我可以在其中单独或成组访问这些线程? 我自己的解决方案是创建一个类,但是自然地,我希望使用更可靠的本机类。 提前致谢! 编辑 显然,功能对于最佳方法非常重要。好吧,我举一个例子: 我有一个基本上可以同时搜索大量信息的应用程序,因此我正在使用线程。但是,每个线程仅需要执行整个操作的一部分,因此我希望添加其他参数来