标签: thread-safety

如何同时入队和出队?

我有一个带有两个线程的简单场景,其中第一个线程永久读取一些数据并将该数据排入队列.第二个线程首先从该队列中查看单个对象并进行一些条件检查.如果这些是好的,单个对象将被出列并传递给某些处理.

我试图使用ConcurrentQueue这是一个简单队列的线程安全实现,但这个问题是所有调用都是阻塞.这意味着如果第一个线程将对象排入队列,则第二个线程无法查看或出列对象.

在我的情况下,我需要在最后排队并同时从队列的开头出队.

C#的锁定语句也会.

所以我的问题是,是否可以并行执行这两个操作而不会以线程安全的方式相互阻塞.

这些是我的第一次尝试,这是我的问题的类似示例.

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Scenario {
    public class Program {
        public static void Main(string[] args) {
            Scenario scenario = new Scenario();
            scenario.Start();
            Console.ReadKey();
        }

        public class Scenario {
            public Scenario() {
                someData = new Queue<int>();
            }

            public void Start() {
                Task.Factory.StartNew(firstThread);
                Task.Factory.StartNew(secondThread);
            }

            private void firstThread() {
                Random random = new Random();
                while (true) {
                    int newData = random.Next(1, 100);
                    someData.Enqueue(newData);
                    Console.WriteLine("Enqueued " + newData);
                }
            }

            private void …
Run Code Online (Sandbox Code Playgroud)

.net c# queue nonblocking thread-safety

1
推荐指数
1
解决办法
2272
查看次数

并行流在任务完成之前完成

我使用此方法初始化具有默认值的ArrayList:

private ArrayList<Integer> createArrayList(int size, int defaultValue)
{
    ArrayList<Integer> arrayList = new ArrayList<>(size);
    IntStream.range(0, size ).parallel().forEach(i->{arrayList.add(defaultValue);});

    return arrayList;
}
Run Code Online (Sandbox Code Playgroud)

令人惊讶的是,如果我通过单元测试检查返回数组的大小,它不是固定数字,并且几乎总是小于请求的大小.

如果我删除parallel()它的大小总是按要求.

为什么会这样?

java parallel-processing thread-safety java-stream

1
推荐指数
1
解决办法
183
查看次数

ConcurrentBag的性能,多次读取,罕见的修改

我正在尝试建立一个模型,在该模型中,我将多次读取整个集合,并对其进行罕见的添加和修改。

我以为我ConcurrentBag在阅读文档时可能会在.NET中使用它,因此对于并发读写来说应该是不错的选择。

代码如下所示:

public class Cache 
{     
   ConcurrentBag<string> cache = new ConcurrentBag<string>();

   // this method gets called frequently
   public IEnumerable<string> GetAllEntries()
   { 
         return cache.ToList();
   }

   // this method gets rarely called 
   public void Add(string newEntry) 
   {  
         // add to concurrentBag
   }

   public void Remove(string entryToRemove)
   {
        // remove from concurrent bag
   } 
} 
Run Code Online (Sandbox Code Playgroud)

但是,我已经对该ConcurrentBag类进行了反编译,并且GetEnumerator始终会进行锁定,这意味着对GetAllEntries的任何调用都会锁定整个集合,并且将无法执行。

我正在考虑解决此问题,并使用列表以这种方式进行编码。

 public class Cache 
 {     
    private object guard = new object();

    IList<string> cache = new List<string>();

   // this method gets …
Run Code Online (Sandbox Code Playgroud)

.net c# multithreading thread-safety

1
推荐指数
1
解决办法
437
查看次数

System.MulticastDelegate`的线程安全吗?

我正在寻找可能对此有更多了解的人,我的直觉告诉我答案是“不,它不是线程安全的”,但我想确定。

为了说明我的问题,我为此类提供了一些背景信息

public class MyContext
{
    private readonly object _lock = new object();
    public delegate bool MyDelegate(MyContext context);
    private MyDelegate _multicastDelegate;

    public MyContext()
    {
        _multicastDelegate = null;
    }

    public void AddDelegate(MyDelegate del)
    {
        lock(_lock)
        {
            _multicastDelegate += del;
        }
    }

    public void RemoveDelegate(MyDelegate del)
    {
        lock(_lock)
        {
            _multicastDelegate += del;
        }
    }

    public void Go()
    {
        _multicastDelegate.Invoke(this);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:我在上面的示例中添加了锁,但这实际上不是我的问题的重点。


我试图更好地了解保存调用列表的数组是否是线程安全的。坦白说,我不清楚这是如何组合在一起的,可以提供一些帮助。

根据我发现的文档,唯一没有提供真正洞察力的报价如下:

MulticastDelegate具有由一个或多个元素组成的委托链接列表,称为调用列表。调用多播委托时,调用列表中的委托按照它们出现的顺序被同步调用。如果在执行列表期间发生错误,则会引发异常。

https://msdn.microsoft.com/zh-CN/library/system.multicastdelegate.aspx

提前致谢。

c# multithreading thread-safety multicastdelegate

1
推荐指数
1
解决办法
167
查看次数

迭代时从数组中删除项目的安全方法?

我有一系列我想要执行的闭包,并以安全的方式删除每个项目.

如果我只是这样做:

array.forEach { $0() }
array.removeAll()
Run Code Online (Sandbox Code Playgroud)

项目可能在执行forEachremoveAll执行之间偷偷摸摸,所以我可能会删除在前一行中没有执行的元素.

这样的事情会更安全吗?

extension Array {

    mutating func removeEach(handler: @escaping (Element) -> Void) {
        enumerated().forEach { handler(remove(at: $0.offset)) }
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有一种安全的方法以算法的方式执行此操作而不是使用线程锁?

arrays algorithm thread-safety swift swift4

1
推荐指数
1
解决办法
526
查看次数

Go中的单例实现

我有一个结构:

type cache struct {
    cap     int
    ttl     time.Duration
    items   map[interface{}]*entry
    heap    *ttlHeap
    lock    sync.RWMutex
    NoReset bool
}
Run Code Online (Sandbox Code Playgroud)

它实现的接口:

type Cache interface {
    Set(key, value interface{}) bool
    Get(key interface{}) (interface{}, bool)
    Keys() []interface{}
    Len() int
    Cap() int
    Purge()
    Del(key interface{}) bool
}
Run Code Online (Sandbox Code Playgroud)

函数返回单例:

func Singleton() (cache *Cache) {
    if singleton != nil {
        return &singleton
    }
    //default
    singleton.(cache).lock.Lock()
    defer singleton.(cache).lock.Unlock()
    c := New(10000, WithTTL(10000 * 100))
    return &c
}
Run Code Online (Sandbox Code Playgroud)

我不确定哪种类型应该是我的singleton:

  1. var singleton cache我无法检查零

  2. 如果var singleton …

singleton casting thread-safety go

1
推荐指数
1
解决办法
440
查看次数

挥发性是一种很好的做法,可以避免C#中的竞争条件?

我想知道在特定情况下是否像这样,我们有bool标志,表明是否有一些服务可用:

    private bool isAvailable;
    private void foo()
    {
        if(isAvailable)
        {
            isAvailable = false;
            DoSomething();
            isAvailable = true;
        }
    }
Run Code Online (Sandbox Code Playgroud)

在多线程环境中将bool字段设置为volatile是否足够,或者使用锁甚至是Monitor更好.

在这种特定情况下,如果此时服务不可用,则不需要等待它再次可用.

.net c# multithreading thread-safety

1
推荐指数
1
解决办法
373
查看次数

Java线程安全代码

我在网上看到了下面的代码,它说"代码不是线程安全的".我不明白为什么?因为,以下每个线程运行getList都不会让任何其他线程到达getList().

public class MyClass {
    private List<String> list;

    public static void main (String[] args) throws InterruptedException {
        MyClass obj = new MyClass();

        Thread thread1 = new Thread(() -> {
            System.out.println("thread1 : " + System.identityHashCode(obj.getList()));
        });
        Thread thread2 = new Thread(() -> {
            System.out.println("thread2 : " + System.identityHashCode(obj.getList()));
        });

        thread1.start();
        thread2.start();
    }

    private List<String> getList () {
        if (list == null) {
            list = new ArrayList<>();
        }
        return list;
    }
}
Run Code Online (Sandbox Code Playgroud)

java multithreading thread-safety

1
推荐指数
1
解决办法
85
查看次数

是用C/C++编写或加载两个指令的128位int吗?

我知道int128_tC和C++中存在一个类型.

如果我有两个线程,一个从包含这个128位整数的存储器位置读取,另一个正在写入它.

是否有可能将此值写为两个64位整数写入,还是一个128位整数写入?

c c++ int128 thread-safety

1
推荐指数
2
解决办法
233
查看次数

引擎盖下的Java类构造

考虑我们有这样的类:

class A {
    public B b;

    public void someFunc() { // called sometime
        b = new B();
    }
}
Run Code Online (Sandbox Code Playgroud)

B的构造函数分配一些内部变量。

现场b是不是线程安全的在这个意义上另一个线程可以查看b不可─ nullB构造尚未完成。(someFunc执行期间)

我的问题是:从逻辑角度看,构造函数还没有完成怎么办?

对我来说,这种重新排序是不可思议的。

java concurrency thread-safety

1
推荐指数
1
解决办法
102
查看次数