当前位置: 首页 > 面试题库 >

同步跨线程共享但不能同时访问的对象

顾梓
2023-03-14
问题内容

假设我有一个与field共享的对象data。多个线程将共享对该对象的引用以访问该字段。但是,线程永远不会同时访问对象。我需要声明data为volatile吗?

这样的情况如下:

  • 一个类Counter定义一个唯一字段value和一个方法increment
  • 一个线程使计数器递增,然后生成另一个使计数器递增的线程,依此类推。

鉴于程序的逻辑,因此无法并发访问计数器。但是,计数器是在多个线程之间共享的。计数器必须波动吗?

的情况的另一个变体是当多个线程操纵对象X即明文数据,但交替它们的时间执行(使得X是永远不会同时存取)经由另一个目的ý依赖于并发控制(waitnotifysynchronize)。对象X的字段应该可变吗?


问题答案:

仅当在线程之间建立事前关系时,才能保证来自线程的突变对其他线程可见。建立关系后,所有以前的突变均可见。

如果另一个对象正确地同步了对其的访问,则孤立地使用未正确同步的对象可以安全地使用(请参阅《Java Concurrency in Practice》中的
Piggibacking )。

在问题中描述的两种情况下,我认为不需要同步:

  • Thread.start 建立事前发生关系,因此可以看到先前线程的所有突变
  • 对对象X的访问由对象Y同步,这将建立事前发生的关系并使对X的更改可见(我在博客文章中进行了扩展)。

如果您知道从未同时访问过对象X,则很可能有一个对象Y可以间接同步对X的访问,所以很好。我看到的唯一不安全的情况是线程本身是否按时进行中继(例如,通过Thread.sleep或通过循环直到经过一段时间后才进行中继)以确保互斥:在这种情况下,没有建立先发生后关系。



 类似资料:
  • 问题内容: 我已经搜索了很多,但找不到特定的解决方案。关于stackoverflow也有一些问题,但我无法找到满意的答案,所以我再次询问。 我在java中有一个如下类。 我知道如何在Java中使用线程。 现在我想同时执行这两个操作。为此,我创建了两个线程类,一个在运行中执行addString()逻辑,另一个在执行deleteString()逻辑中。我在每个线程的构造函数中传递mylist,但是在对

  • 问题内容: public class Deadlock { static class Friend { private final String name; public Friend(String name) { this.name = name; } public String getName() { return this.name; } public synchronized void b

  • 我有很多消费者组(每个消费者组一个主题)的用例,因此我必须为一个主题/消费者组创建许多ConcurrentMessageListenerContainer实例。但我希望他们共享一个公共线程池,以控制KafkanConsumer的调用。轮询以及记录的处理方式。您认为这与SpringKafka相关吗,还是我必须实现自己的版本来实例化自己的KafakConsumers?

  • 问题内容: 我正在使用Spring,Hibernate和JPA实体管理器。当同时(通过jquery / ajax)获取UI的不同区域时,我想同步对JPA实体管理器的访问,否则会导致对集合异常的共享引用。我该如何实现?我有一个控制器,它在后端调用服务方法,这些服务方法负责在entitymanager上调用get / save等。 问题答案: 您可以使用特定模式在对象上应用锁定。 实体经理: 查询:

  • 问题内容: 代码段-1 代码段-2 尽管第二个代码段在不引起任何竞争条件的情况下运行良好,但第一个代码段未能成功同步同一类的不同实例(RequestObject)之间对静态数据成员的访问。有人可以对此进行更多说明。我想了解为什么第一种方法不起作用。 问题答案: 您将不断创建新的对象,然后对其进行同步,这至少使考虑它变得非常混乱。这样就可以得到以下情况: 线程A保持当前值(假设为0) 线程B排队等待

  • 问题内容: 我正在阅读同步工作。这是示例: 让假定有两个线程和正在访问的方法,如果线程是块则线程将跳过该块,执行下一个块/语句或将等待/阻塞,直到线程离开 块。 第二是什么,为什么在参数中以及什么时候可以 下面是真的吗? 内在锁在对象上: 如果线程A在其中,则无法输入或任何其他同步方法。 问题答案: 1:线程B将等待,直到线程A释放对同步对象的锁定之后,线程A将释放对同步对象的锁定并执行代码。 2