我知道在没有锁的C语言中,增量操作不是原子的。
JVM会在其iinc
指令的实现上添加任何锁吗?
不,它不是,它可能会造成真正的问题。该测试本应打印200000000条,但由于线程干扰,无法打印
static int n;
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
public void run() {
for(int i = 0; i < 100000000; i++) {
n++;
}
}
};
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(n);
}
注意易失性
并不能解决问题。
问题的答案取决于您指的是IINC
指令还是其他答案所指的运算符。
在静态或实例字段上使用只不过是get、increment和set,因此它不是原子的(其他答案对此进行了更详细的解释)。
但是
既然你问IINC指令是否是原子指令,这不是真正的答案。事实上,这个问题的答案中没有一个是针对指令的,它们似乎都是基于实例或静态字段上使用的运算符。
IINC
指令只对局部变量进行操作。顾名思义,它们只是局部的,只能从非常有限的范围内访问。因此,不可能从另一个线程访问局部变量。这意味着指令是否是原子并不重要。
不,不是
原子性和Thread干涉的Java文档
您需要使用synchronized
关键字或使用AtomicXXX
方法来实现线程安全。
更新:
public synchronized void increment() {
c++;
}
或者
AtomicInteger integer = new AtomicInteger(1);
//somewhere else in code
integer.incrementAndGet();
另请阅读:iinc原子在Java吗?
问题内容: 我知道没有锁定的C ++中增量操作不是原子的。 JVM会在其指令执行中添加任何锁吗? 问题答案: 不,这不对 检索c的当前值。 将检索到的值增加1。 将增加的值存储回c中。 原子性和线程干扰的Java文档 您需要使用关键字或使用方法来确保线程安全。 更新 : 要么
问题内容: 我无法通过实验进行检查,也无法从手册页中收集到它。 说我有两个过程,一个是将文件1从目录1移动(重命名)到目录2。假设正在运行的另一个进程同时将directory1和directory2的内容复制到另一个位置。复制是否可能以这种方式发生,即目录1和目录2都将显示文件1-即,目录1在移动之前被复制,目录2在移动之后被第一个进程复制。 基本上,rename()是原子系统调用吗? 谢谢 问题
问题内容: 我正在使用一条语句来添加新记录或更新当前记录。我有多个线程通过多个连接和多个语句(每个线程一个连接和一个语句)来驱动数据库。我一次要批处理50个语句。 我很惊讶在考试中遭到违反。我希望这是不可能的,因为将作为单个事务执行,或者是吗? 我的Java代码如下所示: 查询如下所示: 该错误显示为: 表格上的键是字段上的键。 问题答案: 是原子的,意味着所有更改都已提交或所有更改都已回滚。 在
问题内容: 是原子的吗? 分配对象引用应该是,但是我不确定。 谢谢。 问题答案: 是的 。在Java中,所有引用分配都是原子的。 只需注意,这样的复合语句不是原子的,因为它包含一个对象创建和一个单独的赋值。 另请注意,来自JLS-17.7的 “对long和double变量的分配可能不是原子的”
问题内容: 在Objective-C中,您可以区分原子性质和非原子性质: 根据我的理解,您可以安全地从多个线程读取和写入定义为原子的属性,而同时从多个线程中写入和访问非原子属性或ivars可能导致不确定的行为,包括严重的访问错误。 因此,如果您在Swift中有这样的变量: 我可以安全地并行读写该变量吗?(不考虑这样做的实际含义)。 问题答案: 假设尚无底层文档,这还为时尚早,但是您可以从汇编中学习
问题内容: 参考以下链接:http : //docs.python.org/faq/library.html#what- kinds-of-global-value-mutation-are-thread- safe 我想知道以下情况: 在cPython中将保证是原子的。(x和y都是python变量) 问题答案: 让我们来看看: 它不会出现,他们是原子:x的和y的值可以被另一个线程之间改变字节码,