Java哈希表并发

Java哈希表并发,java,multithreading,concurrency,hashtable,Java,Multithreading,Concurrency,Hashtable,我有一个Java代码,它通过以下方式在哈希表中搜索值: class HTDemo { public static void main(String args[]) { Hashtable balance = new Hashtable(); double bal; balance.put("John Doe", new Double(3434.34)); balance.put("Tom Smith", new Double

我有一个Java代码,它通过以下方式在哈希表中搜索值:

class HTDemo {
    public static void main(String args[]) {
        Hashtable balance = new Hashtable();
        double bal;
        balance.put("John Doe", new Double(3434.34));
        balance.put("Tom Smith", new Double(123.22));
        balance.put("Jane Baker", new Double(1378.00));
        balance.put("Todd Hall", new Double(99.22));
        balance.put("Ralph Smith", new Double(-19.08));

        **System.out.println("John Doe's balance: " + balance.get("John Doe"));**
        **System.out.println("Tom Smith's balance: " + balance.get("Tom Smith"));**
        **System.out.println("Jane Baker's balance: " + balance.get("Jane Baker"));**
    }
 }
现在,我想在多线程上运行它,也就是说,我想修改代码,使get方法(在**内)能够并发工作。有人能帮我怎么做吗。实际上,我面临的问题是在运行时传递哈希表并使其并发。

看一看

一个哈希表,支持检索的完全并发性和可调整的更新预期并发性

要并行化这三条线,您只需

String[] users = { "John Doe", "Tom Smith", "Jane Baker" };
for (final String user : users) {
    new Thread() {
        public void run() {
            System.out.println(user + "'s balance: " + balance.get(user));
        }
    }.start();
}
如果您实际上有一个稍微复杂的场景,我建议您研究一下
ExecutorService
和相关类。

看看

一个哈希表,支持检索的完全并发性和可调整的更新预期并发性

要并行化这三条线,您只需

String[] users = { "John Doe", "Tom Smith", "Jane Baker" };
for (final String user : users) {
    new Thread() {
        public void run() {
            System.out.println(user + "'s balance: " + balance.get(user));
        }
    }.start();
}

如果您实际上有一个稍微复杂的场景,我建议您研究一下
ExecutorService
和相关类。

您不能。哈希表的所有方法都是同步的。请参阅Javadoc。使用HashMap,或者,如果您需要线程安全(您没有提到),使用ConcurrentHashMap。

您不能。哈希表的所有方法都是同步的。请参阅Javadoc。使用HashMap,或者,如果您需要线程安全(您没有提到),使用ConcurrentHashMap。

哈希表是同步的,因此已经是线程安全的。在多线程环境中安全地访问代码不需要其他任何东西

但是,由于实现了线程安全机制(所有方法都是同步的),哈希表已经过时,在高度并发的环境中其性能将非常差,并且提供的迭代器不是线程安全的,如果您在迭代时修改该表,它将失败

底线:使用ConcurrentHashMap,如果可以,使用泛型:

Map<String, Double> balance = new ConcurrentHashMap<String, Double> ();
有一个原子性问题:John帐户上的余额可能在调用
balance.get(…)
和支付授权之间发生了变化


如果这是您的一个用例,您将需要引入额外的同步层。

哈希表是同步的,因此已经是线程安全的。在多线程环境中安全地访问代码不需要其他任何东西

但是,由于实现了线程安全机制(所有方法都是同步的),哈希表已经过时,在高度并发的环境中其性能将非常差,并且提供的迭代器不是线程安全的,如果您在迭代时修改该表,它将失败

底线:使用ConcurrentHashMap,如果可以,使用泛型:

Map<String, Double> balance = new ConcurrentHashMap<String, Double> ();
有一个原子性问题:John帐户上的余额可能在调用
balance.get(…)
和支付授权之间发生了变化


如果这是您的一个用例,您将需要引入一个额外的同步层。

也许您在hashmap上使用Hashtable是因为您想要访问您的多线程环境。这些同步的集合现在已经过时了,因为它们确实不能解决同步问题。他们实际上已经雾化添加或移动了。 但它们不能解决一个简单的场景,即在map中,您需要在添加之前先检查密钥存在的位置

Collection.synchronozimap()是解决并发性问题的先行者,但在密集的多线程环境中也失败了


最终,首选的方法是使用并发API。它们通过ConcurrentMap.putIfAbsent方法解决上述问题。

也许您使用Hashtable而不是hashmap是因为您希望访问多线程环境。这些同步的集合现在已经过时了,因为它们确实不能解决同步问题。他们实际上已经雾化添加或移动了。 但它们不能解决一个简单的场景,即在map中,您需要在添加之前先检查密钥存在的位置

Collection.synchronozimap()是解决并发性问题的先行者,但在密集的多线程环境中也失败了


最终,首选的方法是使用并发API。它们通过ConcurrentMap.putIfAbsent方法解决一些问题,如我上面所述。

您的问题是“如何创建新线程?”还是“如何安全地处理对共享数据的多线程访问?”@DNA,第二个问题。我想知道如何修改代码以安全地处理它。你的问题不够精确。如果在线程中填充映射,然后启动仅从映射读取的线程,则无需执行任何操作。如果您以读写方式访问它,并且一次只对单个条目感兴趣,因为哈希表是同步的,所以您不需要做任何事情。在其他情况下(如原子地添加或获取两个条目),则需要特殊的同步。您的问题太模糊,无法回答。您的问题是“如何创建新线程?”还是“如何安全地处理对共享数据的多线程访问?”@DNA,第二个。我想知道如何修改代码以安全地处理它。你的问题不够精确。如果你在一个线程中填充映射,然后启动只从映射中读取的线程,你不需要做任何事情。如果你以读写方式访问它,并且一次只对单个条目感兴趣,因为哈希表是同步的,那么y你不需要做任何事情。在其他情况下(就像以原子方式添加或获取两个条目一样,您需要进行特殊的同步。您的问题太模糊,无法回答。即使是ConcurrentHashMap也不一定能神奇地确保所有内容的安全和正确。例如,如果映射中的两个条目必须以原子方式存储或检索,则仍然需要进行外部同步。@JBNizet Of当然——读到这个问题,我想阿托米