我只是一个非开发人员,所以我的问题可能非常简单!
我只是在测试Java多线程的东西,这不是真正的代码。我想知道如何在 Java 中同时更新两个成员变量,以防我们希望它们都同步。举个例子:
public class Testing
{
private Map<String, Boolean> itemToStatus = new ConcurrentHashMap<>();
private Set<String> items = ConcurrentHashMap.newKeySet();
public static void main(String[] args)
{
(new Testing()).start("ABC");
}
public void start(String name) {
if (name.equals("ABC")) {
itemToStatus.put(name, true);
items.add(name);
}
}
}
在这种情况下(当然,想象一下多线程),我希望能够保证对< code>items和< code>itemToStatus的任何读取总是返回相同的结果。
因此,如果代码在< code>itemToStatus.put(name,true)行中,并且其他线程询问< code > items . contains(name),它将返回false。另一方面,如果另一个线程请求< code > itemtostatus . contains key(name);它将返回true。我不希望这样,我希望它们给出相同的值,如果这有意义的话?
我怎样才能使这两个变化原子化?这行吗?
if (name.equals("ABC")) {
synchronised(this) {
itemToStatus.put(name, true);
items.add(name);
}
}
不过,我不明白为什么这会奏效。我想这就是你需要锁什么的情况?
干杯
简短的回答是肯定的:通过同步代码块,就像您在上一个代码片段中所做的那样,您使类成为线程安全的,因为该代码块是唯一读取或修改类状态的代码块(由两个实例变量表示)。同步(this)
的含义是您使用对象的实例(this
)作为锁:当一个线程进入该代码块时,它会获得锁,阻止其他线程进入相同的代码块,直到线程退出代码块时释放它。
仅仅同步写入是不起作用的。您还需要同步(在同一个对象上)对项目
和itemToState
集合的读取访问。这样,如果另一个线程正在更新这两个集合,则没有线程可以读取任何内容。请注意,以这种方式同步意味着您不需要Con的HashMap
或Con的HashSet
;普通的旧HashMap
和HashSet
将起作用,因为您提供了自己的同步。
例如:
public void start(String name) {
if (name.equals("ABC")) {
synchronized (this) {
itemToStatus.put(name, true);
items.add(name);
}
}
}
public synchronized boolean containsItem(String name) {
return items.contains(name);
}
public synchronized boolean containsStatus(String name) {
return itemToStatus.containsKey(name);
}
这将保证如果进行了该调用,则< code>containsItem返回的值也将由< code>containsStatus返回。当然,如果您希望返回值在一段时间内保持一致(比如首先调用< code>containsItem(),然后调用< code>containsStatus()),您将需要更高级别的同步。
问题内容: 最近,我正在阅读一个教程,其中遇到了一条声明: “Java语言规范保证了读取或写入的变量是一个原子操作(除非该变量的类型的或)类型的操作变量或者是只有当它们与申报原子的关键字。” 或提供类似的方法,并且其是原子的。 我对以上声明感到有些困惑。.请您澄清一下 何时使用 或 使用类。 问题答案: 否则(与作为一个)是一个原子操作。但是执行操作不是原子操作,因为它需要读取a的值,递增和写入a
原子操作是否足够安全,可以在多线程应用程序中使用它,而不会导致竞争条件和其他并发问题?假设我们不担心可见性(我们从CPU读取/写入所有内容)。
我找到了关于线程安全的代码,但它没有来自给出示例的人的任何解释。我想知道为什么如果我不在“count”之前设置“synchronized”变量,那么count值将是非原子的(总是=200是期望的结果)。谢谢
如果有多个Java线程同时写入同一个套接字实例,这会影响从同一个套接字读取的对象的完整性吗?例如,对象的内容是否会被弄乱等。对象的顺序可以是随机的。
问题内容: 我从一个非常简单的多线程示例开始。我试图做一个线程安全的计数器。我想创建两个线程,使计数器间歇地增加到1000。以下代码: 据我所知,while循环现在意味着只有第一个线程才能访问计数器,直到达到1000。输出: 我该如何解决?如何获得共享计数器的线程? 问题答案: 两个线程都可以访问您的变量。 您看到的现象称为线程饥饿。输入代码的受保护部分后(很抱歉,我之前错过了它),其他线程将需要
我们正在尝试使用以下查询将数据流式传输到postgres 11: 基本上“在表中插入记录,如果它已经存在 - 我们希望将此查询连接到消息队列,并在多个实例中的高并发环境中运行它。使用此查询,可能会从不同的连接访问同一行。对我们来说,只有具有最高交付时间戳的项目最终才能进入表是至关重要的 根据文件: 在冲突时,DO UPDATE保证原子插入或更新结果;如果没有独立的错误,那么即使在高并发的情况下,这