volatile
在有两个线程对其进行读/写操作并且不希望取出锁的开销(或潜在的死锁风险)的情况下,有时会使用实例变量。例如,计时器线程会定期更新一个int
ID,该int ID在某些类中作为getter公开:
public class MyClass {
private volatile int id;
public MyClass() {
ScheduledExecutorService execService = Executors.newScheduledThreadPool(1);
execService.scheduleAtFixedRate(new Runnable() {
public void run() {
++id;
}
}, 0L, 30L, TimeUnit.SECONDS);
}
public int getId() {
return id;
}
}
我的问题:鉴于JLS只能保证32位读取将是原子有任何一点 曾经 使用挥发性长时间?(即64位)。
警告 :请不要回答说使用volatile
over
synchronized
是预先优化的情况;我很清楚如何/何时使用,synchronized
但在某些情况下volatile
更可取。例如,当定义用于单线程应用程序中的Spring
bean时,我倾向于使用volatile
实例变量,因为不能保证Spring上下文将在主线程中初始化每个bean的属性。
不知道我是否正确理解了您的问题,但不确定JLS
8.3.1.4。volatile字段
指出:
字段可以声明为volatile,在这种情况下,Java内存模型可确保所有线程看到的变量值都是一致的(第17.4节)。
也许更重要的是,JLS
17.7双重和长期的非原子处理:
长的双17.7非原子治疗和
[…]对于Java编程语言存储器模型的目的,对非易失性长或双值的单个写入被视为两个单独的写操作:一个用于每个32位半。这可能导致线程从一次写入中看到64位值的前32位,而从另一次写入中看到后32位的情况。
易失的long和double值的写入和读取始终是原子的。 引用的写入和读取始终是原子的,无论它们是实现为32位还是64位值。
也就是说,“整个”变量受volatile修饰符保护,而不仅仅是两个部分。这使我断言说,对s 使用volatile 比对s 更为重要
,因为对于非易失性longs / doubles来说, 甚至读取 都不是原子的。long``int
__
有什么理由使用而不是吗?
问题内容: 使用“抽象方法”有什么意义?抽象类不能实例化,但是抽象方法呢?他们只是在这里说“您必须实现我”,如果我们忘记了它们,编译器会抛出错误? 这还意味着其他吗?我还阅读了有关“我们不必重写相同的代码”的内容,但是在抽象类中,我们仅“声明”了抽象方法,因此我们将不得不在子类中重写代码。 您能帮我多了解一点吗?我检查了有关“抽象类/方法”的其他主题,但没有找到答案。 问题答案: 除了提醒您必须实
搜索字符并不容易。我在看CSS的时候发现了这个 这是什么意思?
如果我分割成多个数据库,所有的东西仍然是单线程的,而且我仍然只能使用一个核心。如果我只是在同一个盒子上启动另一个Redis实例,我将使用一个额外的核心。最重要的是,我不能给Redis数据库命名,也不能给它们任何更符合逻辑的标识符。那么,说完所有这些,为什么/什么时候我会想要使用多个Redis数据库,而不是仅仅为我想要的每个额外数据库构建一个额外的Redis实例呢?与此相关的是,为什么Redis不尝
问题内容: 我们已经成功地使用pm2在服务器上运行应用程序。我们目前正在迁移至docker,我们看到了http://pm2.keymetrics.io/docs/usage/docker- pm2-nodejs/ 但是,将两者一起使用的意义何在?码头工人不提供pm2所做的一切吗? 问题答案: 通常在docker内部使用pm2是没有意义的。 PM2和Docker都是流程管理器,它们都可以执行日志转发
问题内容: 这可能是一个愚蠢的问题,但这不是在我的脑海中点击。 在Django中,惯例是将特定于应用程序的所有静态文件(即css,js)放入名为static的文件夹中。所以结构看起来像这样: 在我有: 因此,当我运行命令时: 它会在根目录下创建一个文件夹(与相同的目录myapp/) 这有什么意义呢?它不只是创建我所有静态文件的副本吗? 问题答案: 将来自多个应用程序的静态文件收集到一个路径中 那么