我一直在使用C#,并且最近开始致力于为我的侧面项目添加并行性.因此,根据微软的说法,读取和写入int甚至浮点数都是原子的
我确信这些原子性要求在x86架构上运行得很好.但是,在ARM(可能没有硬件浮点支持)等体系结构上,似乎这些保证很难.
问题只是因为'int'总是32位而变得更加重要.有许多嵌入式设备无法自动执行32位写入.
这似乎是C#中的一个根本错误.保证这些数据类型的原子性不能轻松完成.
这些原子性保证如何在没有FPU或32位写入的架构上实现?
我使用下面的类通过同步或异步使用套接字将数据发送到我们的消息队列,如下所示.这取决于我是否要调用同步或异步方法在套接字上发送数据的要求.大多数情况下,我们将异步发送数据,但有时我可能需要同步发送数据.
sendAsync - 它以异步方式发送数据,我们不会阻塞正在发送数据的线程.如果未收到确认,则它将再次从SendToQueue仅在构造函数中启动的后台线程重试.send - 它在套接字上同步发送数据.它在内部调用doSendAsync方法,然后在特定的超时时间内休眠,如果没有收到确认,则从cache桶中删除,这样我们就不会再次重试.因此,上述两种方法之间的唯一区别是 - 对于异步情况,如果没有收到确认,我需要不惜一切代价重试但是对于同步我根本不需要重试,这就是为什么我在PendingMessage类中存储更多状态的原因.
ResponsePoller是一个类,它接收发送到特定套接字上的消息队列的数据的确认,然后调用handleAckReceived下面的方法删除地址,以便我们在收到确认后不重试.如果收到确认,那么套接字是活的,否则它已经死了.
public class SendToQueue {
private final ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
private final Cache<Long, PendingMessage> cache = CacheBuilder.newBuilder()
.maximumSize(1000000)
.concurrencyLevel(100)
.build();
private static class PendingMessage {
private final long _address;
private final byte[] _encodedRecords;
private final boolean _retryEnabled;
private final Object _monitor = new Object();
private long _sendTimeMillis;
private volatile boolean _acknowledged;
public PendingMessage(long address, byte[] encodedRecords, boolean retryEnabled) …Run Code Online (Sandbox Code Playgroud) 我在couchdb文档中有一个列表元素.假设这些是3个文档中的3个元素:
{ "id" : "783587346", "type" : "aList", "content" : "joey", "sort" : 100.0 }
{ "id" : "358734ff6", "type" : "aList", "content" : "jill", "sort" : 110.0 }
{ "id" : "abf587346", "type" : "aList", "content" : "jack", "sort" : 120.0 }
Run Code Online (Sandbox Code Playgroud)
视图检索所有"aList"文档并按"sort"排序显示它们.
现在我想移动元素,当我想将"jack"移动到中间时,我可以在一次写入中执行此原子操作并将其排序键更改为105.0.视图现在以新的排序顺序返回文档.
经过大量的排序后,我可能会在几年后使用50.99999和50.99998之类的排序键,并且在极端情况下会耗尽数字?
您能推荐什么,有更好的方法吗?我宁愿将这些元素保存在单独的文档中.不同的用户可以并行编辑不同的列表元素.
用户也可能同时更改文档顺序(当2个用户想要将两个不同的文档(如joey和jill)移动到最后时,也可能会变得棘手,让我们说"sort"= 130.0同时).
也许有更好的方法?
我错过了CouchDb交易的内容吗?
database-design couchdb transactions atomicity data-structures
我正在阅读有关数据库的ACID属性.原子性和一致性似乎非常密切相关.我想知道是否有任何情况我们需要支持Atomicity但不支持Consistency,反之亦然.一个例子真的会有所帮助!
刚刚发现以下声明作为利益 immutable object
不可变对象总是具有"失败原子性"(Joshua Bloch使用的术语):如果不可变对象抛出异常,它永远不会处于不合需要或不确定状态.
任何人都可以更详细地解释它,为什么会这样呢?
在Ruby中,如果array被许多线程修改,则此代码不是线程安全的:
array = []
array << :foo # many threads can run this code
Run Code Online (Sandbox Code Playgroud)
为什么<<操作不是线程安全的?
主题标题应该是自我探索的......我在下面的方法规范中有点困惑AtomicBoolean:
java.util.concurrent.atomic.AtomicBoolean#compareAndSetjava.util.concurrent.atomic.AtomicBoolean#getAndSet我的断言是,当在if条件中用作布尔子句时,两者都会产生相同的行为:
public class Test {
private AtomicBoolean flag = AtomicBoolean(false);
public void processSomeAction() {
if (flag.getAndSet(false)) { // Shouldn't this be similar to flag.compareAndSet(false)
// process some action
}
}
//...
private void internalMutatorMethod() {
// do some staff then update the atomic flag
flas.set(true);
}
}
Run Code Online (Sandbox Code Playgroud)
假设我想要检索当前标志值并自动更新它,两个方法是否应该产生相同的行为?
如果我错过内部差异,我将非常感谢有关如何以及何时使用这些解释的任何解释.
我想用Java实现一个循环计数器.每个请求的计数器应该(原子地)递增,并且在达到上限时应该翻转到0.
实现这一点的最佳方法是什么,是否有任何现有的实现?
关于多线程编程,我陷入了困惑,希望有人可以来帮助我.
在做了相当多的阅读之后,我已经明白我应该能够在64位系统1上原子地设置64位int的值.
我发现很多这种阅读很困难,所以我想我会尝试做一个测试来验证这一点.所以我用一个线程编写了一个简单的程序,它将一个变量设置为两个值中的一个:
bool switcher = false;
while(true)
{
if (switcher)
foo = a;
else
foo = b;
switcher = !switcher;
}
Run Code Online (Sandbox Code Playgroud)
另一个线程将检查以下值foo:
while (true)
{
__uint64_t blah = foo;
if ((blah != a) && (blah != b))
{
cout << "Not atomic! " << blah << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我设置a = 1844674407370955161;和b = 1144644202170355111;.我运行这个程序并没有输出警告我blah不是a或b.
很好,看起来它可能是一个原子写...但是,然后,我改变了第一个线程设置a和b直接,如下:
bool switcher = false;
while(true)
{ …Run Code Online (Sandbox Code Playgroud) 在ARM架构上,遗憾的是我不确切知道它是什么芯片,是32位int读/写原子?
对基本类型的读/写有什么保证吗?
atomicity ×10
java ×4
atomic ×2
c ×2
.net ×1
arm ×1
c# ×1
c++ ×1
concurrency ×1
consistency ×1
couchdb ×1
counter ×1
database ×1
immutability ×1
interlocked ×1
object ×1
ruby ×1
transactions ×1