避免在Java中丢失更新而不直接使用同步

避免在Java中丢失更新而不直接使用同步,java,synchronization,Java,Synchronization,我想知道是否有可能避免丢失更新问题,即多个线程更新同一日期,同时避免使用synchronized(x){} 我将进行大量的添加和增量: val++; ary[x] += y; ary[z]++; 我不知道java如何编译这些字节代码,如果一个线程可以在这些语句块中的一个字节中被中断。换句话说,这些语句是线程安全的吗 另外,我知道Vector类是同步的,但我不确定这意味着什么。以下代码是否是线程安全的,因为i位置的值不会在vec.get(i)和vec.set(…)之间更改 class-myCla

我想知道是否有可能避免丢失更新问题,即多个线程更新同一日期,同时避免使用
synchronized(x){}

我将进行大量的添加和增量:

val++;
ary[x] += y;
ary[z]++;

我不知道java如何编译这些字节代码,如果一个线程可以在这些语句块中的一个字节中被中断。换句话说,这些语句是线程安全的吗

另外,我知道Vector类是同步的,但我不确定这意味着什么。以下代码是否是线程安全的,因为
i
位置的值不会在
vec.get(i)
vec.set(…)
之间更改

class-myClass{
Vector vec=新向量(整数);
公共方法(){
对于(int i=0;i

提前感谢。

为了线程化的目的,
+
+=
被视为两个操作(四个用于
)。因此,更新可能会相互冲击。不仅仅是一个,而且一个在错误时刻运行的调度程序可能会消除毫秒级的更新

java.util.concurrent.atomic
是您的朋友

假设您不介意每个元素单独更新,并且不更改大小(!),则代码可以变得安全,如下所示:

它的优点是没有锁(!)和装箱。该实现也很有趣,您需要了解它是否需要执行更复杂的更新(例如,随机数生成器)。

vec.set()和vec.get()是线程安全的,因为它们不会以丢失集和进入其他线程的方式设置和检索值。这并不意味着你的设置和获取将不会中断

如果您真的要像上面的例子那样编写代码,您可能应该锁定一些东西。而且
synchronized(vec){}
和任何一种都一样好。您在这里要求同步执行两个操作,而不仅仅是一个线程安全操作


即使是java.util.concurrent.atomic,也只能确保一个操作(get或set)安全发生。您需要在一个操作中获取和增量。

除了使用getAndIncrement和类似的操作之外?(技术上实现为多个操作,但如果失败则在一个循环中。)这有点低级。java.util.concurrent是一个更普遍有用的级别。
class myClass {
  Vector<Integer> vec = new Vector<>(Integer);

  public void someMethod() {
    for (int i=0; i < vec.size(); i++)
      vec.set(i, vec.get(i) + value);
  }
}
for (int i=0; i < vec.size(); i++) {
    synchronized (vec) {
        vec.set(i, vec.get(i) + value);
    }
}
private final AtomicIntegerArray ints = new AtomicIntegerArray(KNOWN_SIZE);
[...]
    int len = ints.length();
    for (int i=0; i<len; ++i) {
        ints.addAndGet(i, value);
    }
}