我正在寻找改进一个我相信当它的输入在多个工作线程之间共享时不是线程安全的包.根据TDD原则,我应该首先编写一些失败的测试,这些测试在评估问题时肯定会有用.
我意识到这并不是一件简单的事情,而且天真的多线程测试将是不确定的,因为操作系统将确定调度以及各种操作交错的确切顺序.我过去看过并使用过MultithreadedTC,这很有用.但是,在这种情况下,我事先知道现有实现的确切位置,从而能够完成一系列覆盖它的测试.
但是,如果你还没有确切知道问题是什么,那么是否有一种很好的方法来编写一个很有可能抛出任何潜在问题的测试?是否有其他人发现有用的图书馆?我是否正确地认为,从纯粹的角度来看,多线程测试用例应该与通常的单线程测试一样是相同的调用和断言,只适用于多个工作线程?
我们欢迎任何有关工具/最佳实践/理念的提议.
只是检查...... _count正在安全访问,对吗?
两个方法都由多个线程访问.
private int _count;
public void CheckForWork() {
if (_count >= MAXIMUM) return;
Interlocked.Increment(ref _count);
Task t = Task.Run(() => Work());
t.ContinueWith(CompletedWorkHandler);
}
public void CompletedWorkHandler(Task completedTask) {
Interlocked.Decrement(ref _count);
// Handle errors, etc...
}
Run Code Online (Sandbox Code Playgroud) 说我有这个简单的方法:
public IEnumerable<uint> GetNumbers()
{
uint n = 0;
while(n < 100)
yield return n++;
}
Run Code Online (Sandbox Code Playgroud)
你会如何使这个线程安全?而且我的意思是你会得到一次枚举器,并且有多个线程处理所有数字而没有任何人得到重复.
我想在某个地方需要使用一个锁,但是哪个锁必须使迭代器块成为线程安全的呢?一般来说,如果你想要一个线程安全,你需要记住IEnumerable<T>什么?或者更确切地说,我猜这将是一个线程安全IEnumerator<T>...?
考虑以下代码:
public synchronized void onSignalsTimeout(List<SignalSpec> specs) {
if (specs != null && specs.size() > 0) {
for (SignalSpec spec : specs) {
ParsedCANSignal timeoutedSignal = new ParsedCANSignal();
SignalsProvider.getInstance().setSignal(spec.name, spec.parent.parent.channel, timeoutedSignal);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我有一个简单的问题:当线程1调用onSignalsTimeout方法时,线程2可以访问在该方法中访问的对象吗?
如果'synchronized'锁只能访问此方法或访问此方法中使用的所有对象,则无法找到任何位置.
在Ruby中对类变量执行写入/读取不是线程安全的.对实例变量执行写入/读取似乎是线程安全的.也就是说,对类或元类对象的实例变量执行写/读是否是线程安全的?
在线程安全方面,这三个(人为的)示例之间有什么区别?
例1: 相互排斥
class BestUser # (singleton class)
@@instance_lock = Mutex.new
# Memoize instance
def self.instance
@@instance_lock.synchronize do
@@instance ||= best
end
end
end
Run Code Online (Sandbox Code Playgroud)
例2: 实例变量存储
class BestUser # (singleton class)
# Memoize instance
def self.instance
@instance ||= best
end
end
Run Code Online (Sandbox Code Playgroud)
例3: 在METACLASS上安装可变存储器
class BestUser # (singleton class)
# Memoize instance
class << self
def instance
@instance ||= best
end
end
end
Run Code Online (Sandbox Code Playgroud) ruby multithreading metaprogramming thread-safety ruby-1.9.2
如果我创建自己的线程(即不是线程池)和我调用的某个地方sleep或任何其他可中断的方法,如果我知道代码中没有其他人在线程上执行中断,则可以忽略InterruptedException .
换句话说,如果线程应该和JVM一样长,这意味着线程不可中断,是否可以安全地假设InterruptedException 永远不会被调用,因此可以吞下异常?
java multithreading exception-handling thread-safety interrupted-exception
可能重复:
从多个线程调用Console.WriteLine
只是想知道多个线程是否调用相同的console.writeline,它会导致死锁吗?
关于Singletons的维基百科文章提到了一些在Java中实现结构的线程安全方法.对于我的问题,让我们考虑具有冗长初始化过程并且同时被许多线程所占据的单身人士.
首先,这个未提及的方法是否是线程安全的,如果是这样,它会同步什么?
public class Singleton {
private Singleton instance;
private Singleton() {
//lots of initialization code
}
public static synchronized Singleton getInstance() {
if(instance == null) {
instance = new Singleton();
}
return instance;
}
}
Run Code Online (Sandbox Code Playgroud)
其次,为什么以下实现线程在初始化时是安全且懒惰的?如果两个线程同时进入该getInstance()方法会发生什么?
public class Singleton {
private Singleton() {
//lots of initialization code
}
private static class SingletonHolder {
public static final Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,在第二个示例中,如果一个线程首先获取实例而另一个线程获取实例并尝试在构造函数在第一个线程中完成之前对其执行操作,该怎么办?那你可以进入一个不安全的状态吗?
我在多线程环境中聚合键的多个值.钥匙事先不知道.我以为我会这样做:
class Aggregator {
protected ConcurrentHashMap<String, List<String>> entries =
new ConcurrentHashMap<String, List<String>>();
public Aggregator() {}
public void record(String key, String value) {
List<String> newList =
Collections.synchronizedList(new ArrayList<String>());
List<String> existingList = entries.putIfAbsent(key, newList);
List<String> values = existingList == null ? newList : existingList;
values.add(value);
}
}
Run Code Online (Sandbox Code Playgroud)
我看到的问题是,每次运行此方法时,我都需要创建一个新的实例,ArrayList然后将其丢弃(在大多数情况下).这似乎是无理滥用垃圾收集器.是否有一种更好的,线程安全的方法来初始化这种结构而不必使用synchronize该record方法?我对使该putIfAbsent方法不返回新创建的元素的决定感到有些惊讶,并且缺少一种延迟实例化的方法,除非它被调用(可以这么说).
有谁知道如何将多个参数传递给Thread.Start例程?
我想扩展类,但C#Thread类是密封的.
以下是我认为代码的样子:
...
Thread standardTCPServerThread = new Thread(startSocketServerAsThread);
standardServerThread.Start( orchestrator, initializeMemberBalance, arg, 60000);
...
}
static void startSocketServerAsThread(ServiceOrchestrator orchestrator, List<int> memberBalances, string arg, int port)
{
startSocketServer(orchestrator, memberBalances, arg, port);
}
Run Code Online (Sandbox Code Playgroud)
顺便说一下,我用不同的协调器,天平和端口启动了许多线程.请考虑线程安全.
thread-safety ×10
java ×5
c# ×3
.net ×2
android ×1
console ×1
deadlock ×1
ienumerable ×1
interlocked ×1
parameters ×1
ruby ×1
ruby-1.9.2 ×1
singleton ×1