我有一些关于
Java的问题.
>弦
我有一个班:
public class Test { private String s; public synchronized void setS(String str){ s = s + " - " + str; } public String getS(){ return s; } }
我在我的设置器中使用“同步”,并避免在我的getter,因为在我的应用程序,有大量的数据获取,很少的设置.必须同步设置以避免不一致.我的问题是:获取并设置变量原子?我的意思是,在多线程环境中,Thread1即将设置变量s,而Thread2即将获得“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); } }
放置和获得原子? HashMap如何处理将元素放入其中?它是否首先删除旧的值,并把现在的一个?我能否得到旧的价值或新的价值?
提前致谢!
解决方法
在第一种情况下,String对于不安全的发布(在“新的”Java内存模型(JMM))中是安全的,所以这是可以的.
理论上说,不是挥发性的,没有最新价值的一些问题,但是最新的含义并不清楚.您可以使用比较 – 沙 – 交换(CAS)循环来替换锁定,但这可能不会给您更多的性能增益,无论锁是否可能被争用.
在HashMap的情况下,如果有另一个线程写入,即使是单个写入程序线程,一个不同步的映射也不安全.事实上,这被发现导致运行流行软件的生产系统的无限循环.问题中的代码实际上为地图使用了两个锁,它位于顶部(尽管如果使用迭代器,则需要显式保持相同的锁).不是最终决定是否阻止包装类不安全发布.如果地图是不稳定的,并且您为每个投入创建了一个新的地图,那么这可以使得在没有同步的情况下是安全的.