Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字节数组多线程_Java_Multithreading_Concurrency_Thread Safety_Race Condition - Fatal编程技术网

Java字节数组多线程

Java字节数组多线程,java,multithreading,concurrency,thread-safety,race-condition,Java,Multithreading,Concurrency,Thread Safety,Race Condition,如果我有多个线程访问getter和setter,那么这段代码是否会遇到任何竞争条件?我不介意getter在set操作期间获取旧数据,但前提是它不会导致异常或获取null ConcurrentHashMap<String, Object> hashMap = new ConcurrentHashMap<String, Object> (); void setByteArray(String string, byte[] byteArray) { hashM

如果我有多个线程访问getter和setter,那么这段代码是否会遇到任何竞争条件?我不介意getter在set操作期间获取旧数据,但前提是它不会导致异常或获取null

ConcurrentHashMap<String, Object> hashMap =
    new ConcurrentHashMap<String, Object> ();

void setByteArray(String string, byte[] byteArray) {
    hashMap.put(string, byteArray.clone());
}

byte[] getByteArray(String string) {
    return ((byte[]) hashMap.get(string)).clone();
}
ConcurrentHashMap hashMap=
新的ConcurrentHashMap();
void setByteArray(字符串,字节[]byteArray){
put(字符串,byteArray.clone());
}
字节[]getByteArray(字符串){
return((字节[])hashMap.get(字符串)).clone();
}
这几乎是线程安全的(如果有这样的事情)。唯一缺少的是声明
hashMap
字段
final
。这保证了地图的真实性

除此之外,我没有发现任何问题(关于线程安全)。是线程安全的,因此存储和检索字节数组也应该是安全的

此外,由于您总是复制字节数组,因此除了存储在映射中的线程外,它们永远不会在线程之间共享。ConcurrentHashMap将安全地将它们发布到所有线程,因为它们从不被修改(这意味着它们实际上是不可变的),所以线程安全是有保证的

最后,根据评论,以下是关于其他一些方面的改进版本:

private final ConcurrentHashMap<String, Object> hashMap =
    new ConcurrentHashMap<String, Object> ();

void setByteArray(String string, byte[] byteArray) {
    hashMap.put(string, byteArray.clone());
}

byte[] getByteArray(String string) {
    Object result = hashMap.get(string);
    if(result == null)
        return null;
    else
        return ((byte[]) result).clone();
}
private final ConcurrentHashMap hashMap=
新的ConcurrentHashMap();
void setByteArray(字符串,字节[]byteArray){
put(字符串,byteArray.clone());
}
字节[]getByteArray(字符串){
对象结果=hashMap.get(字符串);
如果(结果==null)
返回null;
其他的
返回((字节[])结果);
}
第一件事是
hashMap
private
修饰符,因此子类不能存储任何其他对象,例如共享字节数组


第二件事是getter中的null检查。您可能需要替换
返回null抛出新的IllegalArgumentException()或其他一些,基于您的需求。

ConcurrentHashMap
已设置好处理它,因此我的结论是您应该满足您的需求。

看起来没问题,因为
ConcurrentHashMap
处理线程安全,根据规范,您的代码不是线程安全的,不是因为字节,而是因为您使用ConcurrentHashMap的方式

要在映射中添加项目,应在put()上使用putIfAbsent()。 PutIfAbsent()相当于

   if (!map.containsKey(key)){
      return map.put(key, value);
   }
   else {
       return map.get(key);
   }
(可能使用正确的同步块或关键字)


若您只使用put(),则在多线程环境中可能会用新值覆盖现有值

是的,这段代码几乎是线程安全的,但别忘了声明hashmap private和final。因此,如果有人创建子类,他将无法破坏封装和线程安全性。如果经常克隆
byte[]
,可能会非常昂贵。我假设你正在使用多个线程来改进性能,所以我会考虑一个避免克隆字节[S]的策略,建议检查哈希映射。之前为空cloning@BorisTreukhov,子类将无法断开线程安全性。实例化的对象是一个
ConcurrentHashMap
@Nerrve,请看,问题中的代码似乎不是线程安全的。final不仅涉及替换引用,还涉及内存可见性。请看M.Topolnik回答:我很好奇,getByteArray(..)线程安全性如何?它正在执行“先检查后执行”的复合动作,这不是线程安全的。整个操作需要“锁定”,或者该方法可以简单地返回“hashMap.get()”,然后调用线程可以执行检查和克隆部分…@CaptainHastings“检查然后执行”只有在被检查的属性在执行操作之前发生更改时才是错误的。这在这里是不可能的,因为
result
是一个局部变量,并且属性为null。