1.
我有多个线程更新 ConcurrentHashMap。每个线程根据键将整数列表附加到映射条目的值。任何线程都没有删除操作。
这里的要点是我想尽可能地最小化锁定和同步的范围。
我看到computeIf...()方法的文档说“在计算过程中,其他线程在这个地图上尝试的一些更新操作可能会被阻止”,这并不令人鼓舞。另一方面,当我查看它的源代码时,我没有观察到它在整个地图上锁定/同步的位置。
因此,我想知道使用 computeIf...() 和以下自产的“方法 2”的理论性能的比较。
2.
另外,我觉得我在这里描述的问题可能是您可以在 ConcurrentHashMap 上执行的最简化的 check-n-set(或通常是“复合”)操作之一。
然而,我不是很自信,也找不到很多关于如何在 ConcurrentHashMap 上进行这种简单的复合操作而不锁定/同步整个地图的指南。
因此,将不胜感激任何对此的一般性良好实践建议。
public void myConcurrentHashMapTest1() {
ConcurrentHashMap<String, List<Integer>> myMap = new ConcurrentHashMap<String, List<Integer>>();
// MAP KEY: a Word found by a thread on a page of a book
String myKey = "word1";
// -- Method 1:
// Step 1.1 first, try to use computeIfPresent(). doc says it may lock the
// entire …Run Code Online (Sandbox Code Playgroud) 我很惊讶Java的AtomicInteger和AtomicLong类没有模块化增量的方法(因此在达到限制后值会回绕到零).
我想我必须遗漏一些明显的东西.最好的方法是什么?
例如,我想在线程之间共享一个简单的int,我希望每个线程能够增加它,比如mod 10.
我可以创建一个使用同步/锁的类,但有更好,更简单的方法吗?
如果有两个线程调用此问题,那么我可以解决以下代码中解锁后的linux上下文切换问题
inline bool CMyAutoLock::Lock(
pthread_mutex_t *pLock,
bool bBlockOk
)
throw ()
{
Unlock();
if (pLock == NULL)
return (false);
// **** can context switch happen here ? ****///
return ((((bBlockOk)? pthread_mutex_lock(pLock) :
pthread_mutex_trylock(pLock)) == 0)? (m_pLock = pLock, true) : false);
}
Run Code Online (Sandbox Code Playgroud) 如果文件不存在,我需要创建一个文件,试图创建此文件的另一个进程将失败.我甚至需要在创建过程完成向其写入实际数据之前将文件视为"已创建".
我读到了O_EXCL标志open(),所以似乎解决方案存在,但我有几个问题:
open()以便将其视为已创建,然后重新打开以进行写入?我记得在某些时候,我看到了编程挑战,人们被要求用单字操作原子地读取双字.
现在,在我们继续之前,做一些澄清:
我记得,解决方案是读取最高的单词,然后读取最低的单词.然后再次读取最高的单词,如果它没有改变,那么该值可以被认为是一致的.
但是,我不确定了.假设我们有两位数01.
0).22在我们的算法读取下一个部分之前将值更改为.2;03.0.我们读了02,算法认为价值一致 ; 但实际上,它从未如此02.我对这个难题的回忆是否正确?这是我不记得的解决方案吗?
我想做这样的事情:
SELECT * FROM TABLE where *condition*
... TEST for a row being returned
IF NOT
INSERT the row
Run Code Online (Sandbox Code Playgroud)
换句话说,我只想在表中插入一行(如果它还没有).我担心的是,当我测试结果集时,该行实际上可能被另一个进程插入.我不知道这会插入两行.我不希望这种情况发生.
我想在交易中包装这两个陈述,但我怀疑这不是答案; 我不知道事务是否具有类似于在执行时锁定表的效果,从而阻止了我的SELECT和INSERT之间的任何其他插入?这是个问题.
我怀疑最好的方法是在行中的列之间设置一个唯一键,以防止重复插入.但是我仍然想知道我关于使用交易的想法是否完全有效或大量关闭?
假设我有一组文件。如何确保写入所有这些文件是原子的。
我考虑过写入临时文件,只有成功写入后,才对每个文件进行原子重命名。但是一次重命名所有文件并不是原子的。另外,如果我们要追加到这些文件中,这将无法扩展到非常大的文件。
取而代之的是,我想到了实施交易,但是那成了一个单独的项目。我意识到这几乎与实现小型数据库有关。
您将如何在Python中做到这一点?
d = FileWriter.open(['file1', 'file2'], 'wb+')
d.write('add hello world to files')
d.close()
Run Code Online (Sandbox Code Playgroud)
确保d.write是原子的,或者如果失败则至少回滚到原始文件。
使用MS Visual C++ 2012
类具有类型的成员 std::atomic_flag
class A {
public:
...
std::atomic_flag lockFlag;
A () { std::atomic_flag_clear (&lockFlag); }
};
Run Code Online (Sandbox Code Playgroud)
有一个类型A的对象
A object;
Run Code Online (Sandbox Code Playgroud)
谁可以被两个(Boost)线程访问
void thr1(A* objPtr) { ... }
void thr2(A* objPtr) { ... }
Run Code Online (Sandbox Code Playgroud)
如果另一个线程正在访问该对象,则该想法是等待该线程.
问题是:是否有可能用atomic_flag对象构造这样的机制?不是说暂时,我想要一些轻量级的boost :: mutex.
顺便说一下,其中一个线程涉及的进程是一个非常长的查询到获得很多行的dBase,我只需要在发生冲突的某个代码区域中挂起它(当处理每一行时)我不能等待整个线程完成join().
我在每个帖子中试过一些:
thr1 (A* objPtr) {
...
while (std::atomic_flag_test_and_set_explicit (&objPtr->lockFlag, std::memory_order_acquire)) {
boost::this_thread::sleep(boost::posix_time::millisec(100));
}
... /* Zone to portect */
std::atomic_flag_clear_explicit (&objPtr->lockFlag, std::memory_order_release);
... /* the process continues */
}
Run Code Online (Sandbox Code Playgroud)
但没有成功,因为第二个线程挂起.实际上,我并不完全理解该atomic_flag_test_and_set_explicit函数所涉及的机制.如果这样的函数不能立即返回,或者可以延迟直到可以锁定标志.
对我来说,如何获得一个具有这样一个函数的锁定机制并始终设置该值并返回之前的值也是一种谜.没有选项只能读取实际设置.
欢迎任何建议.
在编写使用新引入的线程同步原语的C++ 11代码时,您可以使用轻松的内存排序
std::atomic<int> vv;
int i = vv.load(std::memory_order_acquire);
Run Code Online (Sandbox Code Playgroud)
要么
vv.store(42, std::memory_order_release);
Run Code Online (Sandbox Code Playgroud)
我很清楚为什么这是有道理的.
我的问题是:你的组合vv.store(42, std::memory_order_acquire)和vv.load(std::memory_order_release)也有意义吗?在哪种情况下可以使用它们?这些组合的语义是什么?
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
public class _7_Synchronizing_Data_Access {
private AtomicInteger count;
private void incrementAndReport() {
System.out.print(count.incrementAndGet() + "here"); //does not print
}
public static void main(String[] args) {
ExecutorService service = null;
try {
service = Executors.newFixedThreadPool(20);
_7_Synchronizing_Data_Access manager = new _7_Synchronizing_Data_Access();
for (int i = 0; i < 10; i++)
service.submit(() -> manager.incrementAndReport());
} finally {
if (service != null)
service.shutdown();
}
}
}
Run Code Online (Sandbox Code Playgroud)
运行此程序不输出任何内容 甚至没有NullPointerException.如你所见,我没有实例化count.我希望它会引发错误.这是为什么?
atomicity ×10
c++ ×3
java ×3
c++11 ×2
database ×2
filesystems ×2
linux ×2
boost ×1
boost-thread ×1
concurrency ×1
createfile ×1
inline ×1
java-8 ×1
modulo ×1
postgresql ×1
python ×1
transactions ×1
upsert ×1