在Hashtable中,方法是同步的,而不是表变量。这是否意味着put和putIfAbsent(或remove)可以并行运行?

26 浏览
0 Comments

在Hashtable中,方法是同步的,而不是表变量。这是否意味着put和putIfAbsent(或remove)可以并行运行?

在Java中,Hashtable的各个方法是同步的,而不是表实例变量。这意味着put和putIfAbsent(或remove)仍然可以并行运行,对吗?

这意味着为了绝对的线程安全或写安全,应该使用其他同步选项,如使用Collections.synchronizedMap(对象级互斥同步)或ConcurrentHashMap(分段级同步)!

如果是这样的话,我们就不能简单地说Hashtable是线程安全的,对吗?

0
0 Comments

Hashtable中的方法是同步的,而不是表变量。这意味着put和putIfAbsent(或remove)可以并行运行吗?

我认为你误解了声明方法为"synchronized"的含义。这样的方法是在对象实例上同步的,这意味着在特定的对象实例上只能同时执行一个方法。

哦,好的。那是我的误解。现在我明白了。这是一件需要重新学习和消除误解的事情。

所以基本上,当Java线程进入实例同步的Java方法时,它会获取对象级别的锁,并且当它进入静态同步的Java方法时,它会获取类级别的锁。[来自参考资料]

是的,就是这样。

从上述内容可以看出,问题的出现是因为对synchronized关键字的误解。synchronized关键字用于实现线程同步,使得在同一时间只能有一个线程访问被synchronized修饰的代码块或方法。在Hashtable中,虽然方法是同步的,但是锁定的是对象实例,而不是整个Hashtable。因此,不同的线程可以同时访问Hashtable的不同部分。

解决这个问题的方法是使用ConcurrentHashMap代替Hashtable。ConcurrentHashMap是Java提供的线程安全的哈希表实现,它使用了更加高效的锁机制,能够支持更高的并发性。与Hashtable不同,ConcurrentHashMap允许多个线程同时读取和写入,而不会导致死锁或性能下降。

代码示例:

import java.util.concurrent.ConcurrentHashMap;
public class Example {
    private static ConcurrentHashMap map = new ConcurrentHashMap<>();
    public static void main(String[] args) {
        // 同时启动多个线程进行put操作
        for (int i = 0; i < 10; i++) {
            final int index = i;
            new Thread(() -> {
                map.put(String.valueOf(index), index);
            }).start();
        }
    }
}

在上述示例中,我们使用ConcurrentHashMap替代了Hashtable,并通过多个线程同时进行put操作来测试其并发性能。由于ConcurrentHashMap使用了更加高效的锁机制,多个线程可以同时访问和修改ConcurrentHashMap,而不会出现线程安全的问题。

通过使用正确的线程安全的数据结构,如ConcurrentHashMap,可以解决Hashtable同步方法的并发访问问题。这样可以提高程序的并发性能和可靠性。

0