使用来自其他类的公共静态 HashTable 的同步方法。我怎样才能使这个方法线程安全?
Posted
技术标签:
【中文标题】使用来自其他类的公共静态 HashTable 的同步方法。我怎样才能使这个方法线程安全?【英文标题】:synchronized method that use a public static HashTable from other class. How can I make this method thread safe? 【发布时间】:2015-10-28 10:35:56 【问题描述】:假设我有一个使用其他类的公共静态哈希表的同步方法。我怎样才能使这个方法线程安全?据我了解,任何其他线程都可以更改此 HashTable,因为它在其他类中而不是在持有密钥的类(同步方法的类)中,不是吗?
【问题讨论】:
使用ConcurrentHashMap/HashSet等同步集合Hashtable
已同步。
【参考方案1】:
您对 HashTable 的理解不正确。 HashTable 是同步的和线程安全的。
查看HashTable
的源代码。所有公共方法都是同步的。
public synchronized V put(K key, V value)
public synchronized V get(Object key)
public synchronized boolean contains(Object value)
【讨论】:
谢谢。如果映射在同步方法的同一类中并且映射是私有的,我可以使用 HashMap 代替吗?被同步方法使用时没有其他线程可以更改它? HashMap 未同步。如果你想同步,你可以使用Collections.synchronizedMap(map);
并在同步块中做这些事情。请参考:java67.blogspot.in/2015/02/…
Collections.synchronizedMap 使方法调用原子化,它不会使其完全线程安全,您仍然需要同步块。对于线程安全操作,我更喜欢ConcurrentHashMap
。
这不是我的 qwestion 。如果地图在同步方法的 same 类中并且地图是 private ,我可以改用 HashMap 吗? 同步方法使用时没有其他线程可以更改它?
如果您只在同步块内部使用地图,那么您可以!确保您没有提供在外面访问地图的方式。【参考方案2】:
如果你想在同步方法中使用 HashMap,它可以工作,但前提是所有线程都使用包含方法和 HashMap 的类的相同实例em>,为了更清楚,请看下面的示例:
代码片段
public class SynchronizedCounter
private int c = 0;
public synchronized void increment()
c++;
现在,如果所有线程都使用相同的 SynchronizedCounter 实例,我们确保每次只有一个线程在运行 increment()
方法,但如果每个线程都在实例化自己的 SynchronizedCounter 实例,那么方法不会是线程安全的。
Oracle官方说明here。
【讨论】:
但是 c 不是静态的,在您的示例中它是私有的.. 那么问题是什么?它是线程安全的,不是吗? 如果它是静态公共的,我们必须使用 Atomic Integer ,不是吗? 事件如果你的 HashMap 是静态的,这不会改变同步方法的行为,如果你的线程使用包含你的 HashMap 的类的同一个实例,那么同步方法将只允许一个线程每次运行该函数,但是,如果它们使用不同的实例,则该方法不会阻塞其他线程,无论您的 HashMap 是否为静态。 没有因为 HashMap 是静态的,所以它对所有实例都是一样的。 是的,我的意思是如果它不是静态的..所以如果它是静态的,那么使用相同的实例很重要,如果不是,则不重要以上是关于使用来自其他类的公共静态 HashTable 的同步方法。我怎样才能使这个方法线程安全?的主要内容,如果未能解决你的问题,请参考以下文章
如何在Azure VM上配置IIS站点以接受来自其他外部IP地址的请求?
Fragments 作为静态内部类与独立公共类的设计逻辑是啥?