Java赋值问题 - 这是原子的吗?

Bob*_*Bob 9 java multithreading variable-assignment

我对Java的分配有一些疑问.

  • 字符串

我上课了:

public class Test {
 private String s;

 public synchronized void setS(String str){
  s = s + " - " + str;
 }

 public String getS(){
  return s;
 }
}
Run Code Online (Sandbox Code Playgroud)

我在我的setter中使用"synchronized",并在我的getter中避免它,因为在我的应用程序中,有大量的数据获取,并且设置很少.必须同步设置以避免不一致.我的问题是:获取和设置变量原子?我的意思是,在多线程环境中,Thread1即将设置变量s,而Thread2即将获得"s".有没有办法getter方法可以得到一些不同于s的旧值或s的新值(假设我们只有两个线程)?在我的应用程序中获取新值并不是一个问题,并且获取旧值不是问题.但我能得到别的东西吗?

  • HashMap的获取和推送怎么样?

考虑到这个:

    public class Test {
        private Map<Integer, String> map = Collections.synchronizedMap(new HashMap<Integer, String>());

        public synchronized void setMapElement(Integer key, String value){
         map.put(key, value);
        }

        public String getValue(Integer key){
         return map.get(key);
        }
}
Run Code Online (Sandbox Code Playgroud)

投入和获得原子?HashMap如何处理将元素放入其中?它首先删除旧值并放入现在的值吗?我可以获得除旧值或新值之外的其他值吗?

提前致谢!

Tom*_*ine 6

在第一种情况下,String对于不安全的发布(在"新的"Java内存模型(JMM)中)是安全的,所以这没关系.

volatile理论上不存在没有最新值的问题,但是最新的含义并不清楚.您可以使用compare-sand-swap(CAS)循环替换锁,但是无论锁是否可能发生争用,这可能都不会给您带来太多的性能提升.

在这种情况下HashMap,如果有另一个线程写入它,即使是单个写入器线程,也不安全地读取未同步的映射.实际上,已经发现这会导致运行流行软件的生产系统出现无限循环.问题中的代码实际上对地图使用了两个锁,它位于顶部(尽管如果使用迭代器,您需要显式保持相同的锁).不是final不会被不安全发布安全停止含类.如果mapvolatile,你为每个人创建了一个新的地图put,那么可以在没有同步的情况下使其安全.


Pow*_*ord 6

不是将HashMap包装在某个东西中以使其同步,java.util.concurrency.ConcurrentHashMap而是考虑使用替代方法.

这是HashMap的更新版本,可以保证"检索反映了最近完成的更新操作的结果."