在ConcurrentHashMap的 javadoc中有以下内容:
检索操作(包括get)通常不会阻塞,因此可能与更新操作(包括put和remove)重叠.检索反映了最近完成的更新操作的结果.对于诸如putAll和clear之类的聚合操作,并发检索可能反映仅插入或删除某些条目.类似地,Iterators和Enumerations在迭代器/枚举的创建时或之后的某个时刻返回反映哈希表状态的元素.它们不会抛出ConcurrentModificationException.但是,迭代器设计为一次只能由一个线程使用.
这是什么意思?如果我尝试同时使用两个线程迭代地图会发生什么?如果我在迭代时从地图中添加或删除值会发生什么?
java concurrency multithreading thread-safety concurrenthashmap
我在想,如果您有一个静态方法不同步,但并没有修改任何静态变量是线程安全的?如果方法在其中创建局部变量怎么办?例如,以下代码是否是线程安全的?
public static String[] makeStringArray( String a, String b ){
return new String[]{ a, b };
}
Run Code Online (Sandbox Code Playgroud)
因此,如果我有两个线程连续和同时调用这个方法,一个与狗(说"大丹狗"和"公牛狗")和另一个与猫(说"波斯语"和"暹罗语")我会得到猫和狗在同一个数组?或者猫和狗不会同时在同一个方法的调用内?
是否存在使方法线程安全的整体规则/指南?我知道可能有一百万次一次性情况,但一般情况如何呢?这很简单吗?
是吗?这也适用于静态方法吗?
@Cybis提供的一个答案是:
局部变量不能在线程之间共享,因为每个线程都有自己的堆栈.
静态方法也是如此吗?
如果方法传递给引用对象,那是否会破坏线程的安全性?我做了一些研究,并且有很多关于某些情况的研究,但我希望能够通过使用一些规则来定义遵循的指导方针,以确保方法是线程安全的.
所以,我想我的最终问题是:"是否有一个简短的规则列表定义了一个线程安全的方法?如果是这样,它们是什么?"
编辑这里
有很多好处.我认为这个问题的真正答案是:"没有简单的规则来确保线程安全." 凉.精细.但总的来说,我认为接受的答案提供了一个很好的简短摘要.总有例外.就这样吧.我可以忍受这一点.
我知道复合操作i++
不是线程安全的,因为它们涉及多个操作.
但是检查引用本身是一个线程安全的操作?
a != a //is this thread-safe
Run Code Online (Sandbox Code Playgroud)
我尝试编程并使用多个线程,但它没有失败.我想我无法在我的机器上模拟比赛.
public class TestThreadSafety {
private Object a = new Object();
public static void main(String[] args) {
final TestThreadSafety instance = new TestThreadSafety();
Thread testingReferenceThread = new Thread(new Runnable() {
@Override
public void run() {
long countOfIterations = 0L;
while(true){
boolean flag = instance.a != instance.a;
if(flag)
System.out.println(countOfIterations + ":" + flag);
countOfIterations++;
}
}
});
Thread updatingReferenceThread = new Thread(new Runnable() {
@Override
public void run() …
Run Code Online (Sandbox Code Playgroud) 我有以下课程.
class Test{
public HashSet<string> Data = new HashSet<string>();
}
Run Code Online (Sandbox Code Playgroud)
我需要从不同的线程更改字段"Data",所以我想对我当前的线程安全实现有一些看法.
class Test{
public HashSet<string> Data = new HashSet<string>();
public void Add(string Val){
lock(Data) Data.Add(Val);
}
public void Remove(string Val){
lock(Data) Data.Remove(Val);
}
}
Run Code Online (Sandbox Code Playgroud)
是否有更好的解决方案,直接进入现场并保护它免受多线程的并发访问?
这是我实施的模型:
public class LoginSession {
private static final Gson gson = new Gson();
private String id;
private String name;
private long timestamp;
public LoginSession(String id, String name) {
this.id = id;
this.name = name;
this.timestamp = System.currentTimeMillis();
}
public String toJson() {
return gson.toJson(this);
}
public static LoginSession fromJson(String json) {
checkArgument(!isNullOrEmpty(json));
return gson.fromJson(json, LoginSession.class);
}
}
Run Code Online (Sandbox Code Playgroud)
我认为为每个LoginSession实例创建新的Gson实例是没用的.
但我担心的是线程安全问题.将创建大约1000多个实例/秒.
将Gson实例用作静态字段是否可以?
感谢您的任何建议/更正.
在C#中以最佳性能获取线程安全计数器的方法是什么?
这很简单:
public static long GetNextValue()
{
long result;
lock (LOCK)
{
result = COUNTER++;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
但是有更快的选择吗?
我听说const
意味着线程安全的C++ 11.真的吗?
这是否意味着const
现在是等效的Java的synchronized
?
他们的关键字用完了吗?
最近我尝试从一个线程(UI线程除外)访问一个文本框,并抛出异常.它说了一些关于"代码不是线程安全的",所以我最终编写了一个代表(来自MSDN的示例帮助),然后调用它.
但即便如此,我也不太明白为什么所有额外的代码都是必要的.
更新:如果我检查,我会遇到任何严重的问题
Controls.CheckForIllegalCrossThread..blah =true
Run Code Online (Sandbox Code Playgroud) 我能够通过从IDictionary派生并定义一个私有的SyncRoot对象,在C#中实现一个线程安全的Dictionary:
public class SafeDictionary<TKey, TValue>: IDictionary<TKey, TValue>
{
private readonly object syncRoot = new object();
private Dictionary<TKey, TValue> d = new Dictionary<TKey, TValue>();
public object SyncRoot
{
get { return syncRoot; }
}
public void Add(TKey key, TValue value)
{
lock (syncRoot)
{
d.Add(key, value);
}
}
// more IDictionary members...
}
Run Code Online (Sandbox Code Playgroud)
然后,我在整个消费者(多个线程)中锁定此SyncRoot对象:
例:
lock (m_MySharedDictionary.SyncRoot)
{
m_MySharedDictionary.Add(...);
}
Run Code Online (Sandbox Code Playgroud)
我能够使它工作,但这导致了一些丑陋的代码.我的问题是,是否有更好,更优雅的方式来实现线程安全的字典?
thread-safety ×10
c# ×4
java ×4
concurrency ×2
static ×2
.net ×1
atomic ×1
c++ ×1
c++-faq ×1
c++11 ×1
collections ×1
const ×1
counter ×1
definition ×1
gson ×1
locking ×1
mutex ×1