Java赋值问题 – 这是primefaces的吗?

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

  • 字符串

我有一节课:

public class Test { private String s; public synchronized void setS(String str){ s = s + " - " + str; } public String getS(){ return s; } } 

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

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

考虑到这个:

  public class Test { private Map map = Collections.synchronizedMap(new HashMap()); public synchronized void setMapElement(Integer key, String value){ map.put(key, value); } public String getValue(Integer key){ return map.get(key); } } 

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

提前致谢!

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

理论上存在一些没有最新价值的问题,但是最新的含义并不清楚。 您可以使用compare-sand-swap(CAS)循环替换锁定,但这可能不会给您带来很大的性能提升,无论锁定是否可能存在争用。

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

不要将HashMap包装在某些内容中以使其同步,而是考虑使用java.util.concurrency.ConcurrentHashMap

这是HashMap的更新版本,它保证“检索反映了最近完成的更新操作的结果。”

早期的答案是正确的指向新的(1.5+)JVM,字符串版本是安全的,关于数据损坏。 而你似乎意识到了下行非同步访问; 变化不一定是通过吸气剂可见的。

但是:更有用的问题是:有理由在这里进行同步吗? 如果这只是为了有兴趣了解这一点,这一切都很好。 但对于实际代码,读写的一般规则是,如果两者都存在,则两者都应该同步。 因此,尽管在这种情况下您可以省略同步(可能意味着线程看不到其他线程所做的更改),但这样做似乎没什么好处。

也许Read Write Lock可以解决您的问题?

看看它的文档:

读写锁允许访问共享数据的并发性高于互斥锁允许的并发性。 它利用了这样一个事实:虽然一次只有一个线程(一个编写器线程)可以修改共享数据,但在许多情况下,任何数量的线程都可以同时读取数据(因此读取器线程)。 理论上,使用读写锁所允许的并发性的增加将导致相互使用互斥锁的性能提高。 ….

在multithreading环境中,您需要同步getter以确保客户端看到s最新值。