Java提供 AtomicInteger,AtomicLong等等,基本上编译成 CAS指令在硬件层面.但是,为什么这样AtomicXXX类不存在其他原始类型,如short和浮点数喜欢float和double?
在研究 AtomicInteger 时,我发现这个 API 提供了两种方法。
比较和交换:
如果当前值(称为见证值)==预期值,则以原子方式将该值设置为 newValue,并具有由以下指定的记忆效应
VarHandle.compareAndExchange(java.lang.Object...)
比较并设置:
以原子方式将该值设置为
newValue当前值value == expectedValue,并具有由 指定的记忆效应VarHandle.compareAndSet(java.lang.Object...)。
我无法理解两者之间的区别,请帮助提供合适的例子。
无论引擎如何(例如InnoDB或MyISAM),这种"比较和交换"语句是否始终是原子的?:
UPDATE tbl_name SET locked=1 WHERE id=ID AND locked <> 1;
Run Code Online (Sandbox Code Playgroud)
我问这个是因为我打算使用这个语句进行与事务和非事务数据库表兼容的伪行级锁定.
这是MyISAM推荐的方法,但我不确定这是否适用于InnoDB,因为文档建议使用事务.
我在我的多线程代码中使用incrementAndGet方法AtomicLong来衡量我们的一些客户端代码的性能.
@Override
public void run() {
long start = System.nanoTime();
attributes = client.getAttributes(columnsList);
long end = System.nanoTime() - start;
final AtomicLong before = select.putIfAbsent(end / 1000000L, new AtomicLong(1L));
if (before != null) {
before.incrementAndGet();
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我试图测量多少时间 -
client.getAttributes(columnsList);
正在服用.
据我所知,incrementAndGet方法将以原子方式将当前值增加1.这意味着每个线程可能会等待其他线程递增值.我对吗?意味着它会被封锁?
这也会影响我测量任何方法性能的方式吗?这意味着它会为该测量增加一些额外的时间吗?
为什么我要问这是因为我试图对大部分客户端代码和服务器端代码进行基准测试,如果我需要测量每种方法花费多少时间,那么我这样做就像这样 -
无论我想测量什么代码,我通常将下面的行放在该方法之上
long start = System.nanoTime();
而这两条线路采用相同的方法但却有所不同 ConcurrentHashMap
long end = System.nanoTime() - start;
final AtomicLong before = select.putIfAbsent(end / 1000000L, new AtomicLong(1L));
if (before != null) {
before.incrementAndGet(); …Run Code Online (Sandbox Code Playgroud) 如何从地址窃取2个MSB进行原子操作?我正在努力做一个单词CAS
一个例子
public class Node
{
long key;
long value;
Node lchild; // format is flag1,flag2,address
Node rchild; // format is flag1,flag2,address
}
public void createNode()
{
Node n1 = new Node(); //this should create a node with format 0,0,address1
}
public void setFlag1(Node n1)
{
Now the new address should be in format 1,0,address1
}
public void setFlag2(Node n1)
{
Now the new address should be in format 0,1,address1
}
Run Code Online (Sandbox Code Playgroud)
AtomicReference如果我只需要一个额外的标志,可以使用.
AtomicStampedReference可以使用,但它没有效率,因为它创建了一个包含timeStamp和引用的额外框.
在从指针窃取位时讨论了C中的类似问题
c java java.util.concurrent concurrent-programming compare-and-swap
POSIX兼容的操作系统可以通过文件系统对象(文件和文件夹)以原子方式执行多项操作.这是一个可能的原子操作列表:
是否可以构建比较和交换算法来根据这些操作来操作文件?
假设我们有几个进程在单个文件上执行并发读/写.文件的特点是其修订版.假设修订版已添加到文件名中,并且文件的符号链接可由进程用来读取它.这些进程不能(由于某些原因)与互斥锁,信号量等同步,但它们能够创建辅助文件和文件夹.他们是否能够对文件执行基于修订的比较和交换修改(创建新文件,创建和重命名符号链接),这意味着如果多个进程同时修改它,一个将成功,其余将成功失败了一些错误代码?
该算法必须能够抵抗任何算法步骤中任何过程的突然终止.
轻型事务的Datastax文档指出:
“轻量级事务使用的时间戳机制与正常操作不同,并且混合LWT和正常操作会导致错误。如果轻量级事务用于在分区内的行中写入,则应仅对读写操作使用轻量级事务。 ”
这非常模糊(顺便说一句,对于读操作,LWT甚至意味着什么?)。
混合LWT和普通写入时,对Cassandra内部知识有更深入了解的人可以详细说明可能出现的问题吗?
我最好的猜测是并发性可能存在问题(显然)。但是我以为,如果我(例如)使用插入了一行,IF NOT EXISTS并且如果成功的话,我以后再UPDATE对同一分区进行处理,那会很好。我错了吗?
当谈到使用CAS 循环std::atomic实现时,此链接中的 cppreference给出了以下示例push:
template<typename T>
class stack
{
std::atomic<node<T>*> head;
public:
void push(const T& data)
{
node<T>* new_node = new node<T>(data);
new_node->next = head.load(std::memory_order_relaxed);
while(!head.compare_exchange_weak(new_node->next, new_node,
std::memory_order_release,
std::memory_order_relaxed /* Eh? */));
}
};
Run Code Online (Sandbox Code Playgroud)
现在,我不明白如何将 comestd::memory_order_relaxed用于失败情况,因为据我了解, (与-strongcompare_exchange_weak相同,但为了方便起见,我只是使用弱版本)是失败时的加载操作,这意味着它从另一个线程中成功的 CAS 操作加载,因此它应该使用同步…?std::memory_order_releasestd::memory_order_acquire
while(!head.compare_exchange_weak(new_node->next, new_node,
std::memory_order_release,
std::memory_order_acquire /* There you go! */));
Run Code Online (Sandbox Code Playgroud)
假设,如果“宽松负载”获得旧值之一,最终一次又一次失败,并在循环中停留额外的时间怎么办?
下面这张粗糙的图片是我的大脑被卡住的地方。
T2 的商店在 T1 上不应该可见吗?(通过相互之间具有同步关系)
总结一下我的问题,
std::memory_order_acquire,而不是std::memory_order_relaxed失败呢?std::memory_order_relaxed足够呢?std::memory_order_relaxed失败是否意味着 …The question is about the latest iOS and macOS. Suppose I have the following implementation for an atomic Int64 in Swift:
struct AtomicInt64 {
private var _value: Int64 = 0
init(_ value: Int64) {
set(value)
}
mutating func set(_ newValue: Int64) {
while !OSAtomicCompareAndSwap64Barrier(_value, newValue, &_value) { }
}
mutating func setIf(expectedValue: Int64, _ newValue: Int64) -> Bool {
return OSAtomicCompareAndSwap64Barrier(expectedValue, newValue, &_value)
}
var value: Int64 { _value }
}
Run Code Online (Sandbox Code Playgroud)
Note the value accessor: is it safe?
If not, …
compare-and-swap ×10
atomic ×6
java ×4
c++ ×2
algorithm ×1
atomic-long ×1
atomicity ×1
c ×1
c++11 ×1
cassandra ×1
filesystems ×1
innodb ×1
ios ×1
java-9 ×1
macos ×1
memory-model ×1
myisam ×1
mysql ×1
posix ×1
stdatomic ×1
swift ×1
transactions ×1