我正在尝试理解C#Volatile类.
正如我读到的:
该Volatile.Write方法强制将位置中的值写入调用点.此外,任何早期的程序订单加载和存储必须在调用Volatile.Write之前发生.
该Volatile.Read方法强制在呼叫点读取位置中的值.此外,任何后续的程序订单加载和存储必须在调用Volatile.Read之后发生.
这是否意味着:
internal sealed class ThreadsSharingData {
private Int32 m_flag = 0;
private Int32 m_value = 0;
// This method is executed by one thread
public void Thread1() {
// Note: 5 must be written to m_value before 1 is written to m_flag
m_value = 5;
Volatile.Write(ref m_flag, 1);
}
// This method is executed by another thread
public void Thread2() {
// Note: m_value must be read after m_flag is read
if …Run Code Online (Sandbox Code Playgroud) 我很困惑何时使用Thread.join()以及何时synchronization在多线程应用程序中使用.
根据我的说法,他们都阻止或等待执行由其他一些线程完成.
这个例子必须依次按顺序模式输出10 A,10 B和10 C:
1 : A
2 : A
3 : A
4 : A
5 : A
6 : A
7 : A
8 : A
9 : A
10 : A
1 : B
2 : B
3 : B
4 : B
5 : B
6 : B
7 : B
8 : B
9 : B
10 : B
1 : C
2 : C
3 : C
4 …Run Code Online (Sandbox Code Playgroud) 通过try_lock*,我采取的意思是try_lock(),try_lock_for()和try_lock_until().根据cppreference,这三种方法可能只是虚假地失败.以下是从描述中引用的try_lock_for()
与此同时
try_lock(),false即使互斥锁在某个时刻未被任何其他线程锁定,也允许此函数虚假失败并返回timeout_duration.
我知道可能会发生虚假的唤醒std::condition_variable及其背后的基本原理.但是,互斥量是什么情况?
有一个场景,其中多个线程在比较代码上有竞争条件。
private int volatile maxValue;
private AtomicInteger currentValue;
public void constructor() {
this.current = new AtomicInteger(getNewValue());
}
public getNextValue() {
while(true) {
int latestValue = this.currentValue.get();
int nextValue = latestValue + 1;
if(latestValue == maxValue) {//Race condition 1
latestValue = getNewValue();
}
if(currentValue.compareAndSet(latestValue, nextValue) {//Race condition 2
return latestValue;
}
}
}
private int getNewValue() {
int newValue = getFromDb(); //not idempotent
maxValue = newValue + 10;
return newValue;
}
Run Code Online (Sandbox Code Playgroud)
问题 :
解决这个问题的显而易见的方法是在 if 条件周围添加同步块/方法。使用并发 api 而不使用任何类型的锁来解决这个问题的其他高效方法是什么?
如何摆脱 while 循环,以便我们可以在没有或更少线程争用的情况下获得下一个值? …
我只使用以下代码startTime设置一次保证变量:
public class Processor
{
private Date startTime;
public void doProcess()
{
if(startTime == null)
synchronized(this)
{
if(startTime == null)
{
startTime = new Date();
}
}
// do somethings
}
}
Run Code Online (Sandbox Code Playgroud)
我将通过此代码保证变量实例化一次仅用于任何数量的调用process方法调用.
我的问题是:
是否有替代方法可以使我的代码更简洁?(用于样本删除if和synchronized陈述)
java multithreading synchronization thread-safety thread-synchronization
与无争议的原子变量(例如C++的原子<>)操作相比,它的速度/速度更快/更慢.此外,相对于无争议锁定,有争议的原子变量有多慢?我正在研究的架构是x86-64.
c++ performance multithreading x86-64 thread-synchronization
这里我有一个类,它有两个可以访问List的线程.一个线程定期用更新的副本替换列表,另一个线程将列表的内容绘制到屏幕上.
public class ThreadSafePainter {
private List<String> dataList = new ArrayList<>();
/*
* starts a thread to periodically update the dataList
*/
public ThreadSafePainter() {
Thread thread = new Thread(() -> {
while (true) {
// replace out-dated list with the updated data
this.dataList = getUpdatedData();
// wait a few seconds before updating again
Thread.sleep(5000);
}
});
thread.start();
}
/*
* called 10 times/second from a separate paint thread
* Q: Does access to dataList need to be synchronized?
*/ …Run Code Online (Sandbox Code Playgroud) 无锁数据结构中ABA问题的一种流行解决方案是使用额外的单调递增标记来标记指针.
struct aba {
void *ptr;
uint32_t tag;
};
Run Code Online (Sandbox Code Playgroud)
但是,这种方法存在问题.它真的很慢,并且存在巨大的缓存问题.如果我抛弃标签字段,我可以获得两倍的加速.但这不安全吗?
所以我下一次64位平台的尝试填充了ptr字段中的位.
struct aba {
uintptr __ptr;
};
uint32_t get_tag(struct aba aba) { return aba.__ptr >> 48U; }
Run Code Online (Sandbox Code Playgroud)
但有人告诉我,标签只有16位是不安全的.我的新计划是使用指针对齐缓存行来填充更多标记位,但我想知道它是否有效.
如果无法工作,我的下一个计划是使用Linux的MAP_32BIT mmap标志来分配数据,所以我只需要32位指针空间.
在无锁数据结构中,ABA标记需要多少位?
我正在尝试支持定期清除的哈希图上的并发性。我有一个缓存,可以存储一段时间的数据。每 5 分钟后,此缓存中的数据将发送到服务器。一旦我刷新,我想清除缓存。问题是当我刷新时,当我使用现有密钥执行此操作时,数据可能会写入此映射。我将如何使这个进程线程安全?
data class A(val a: AtomicLong, val b: AtomicLong) {
fun changeA() {
a.incrementAndGet()
}
}
class Flusher {
private val cache: Map<String, A> = ConcurrentHashMap()
private val lock = Any()
fun retrieveA(key: String){
synchronized(lock) {
return cache.getOrPut(key) { A(key, 1) }
}
}
fun flush() {
synchronized(lock) {
// send data to network request
cache.clear()
}
}
}
// Existence of multiple classes like CacheChanger
class CacheChanger{
fun incrementData(){
flusher.retrieveA("x").changeA()
}
}
Run Code Online (Sandbox Code Playgroud)
我担心上面的缓存没有正确同步。有没有更好/正确的方法来锁定这个缓存,这样我就不会丢失数据?我应该创建缓存的深层副本并清除它吗?
既然上面的数据可能被另一个更改器更改,那会不会导致问题?
java concurrency java.util.concurrent thread-synchronization kotlin