java - Java中线程访问非同步方法

标签 java multithreading thread-safety thread-synchronization

我可以请你解释一下 Java 中的线程和同步是如何工作的吗?

我想编写一个高性能的应用程序。在这个应用程序中,我将文件中的数据读取到一些嵌套类中,这些类基本上是 HashMap 的简述。

数据读取完成后,我启动需要遍历数据并对其执行不同检查的线程。然而,线程永远不会改变数据!

如果我可以保证(或至少尝试保证;)我的线程永远不会更改数据,我可以使用它们调用包含数据的对象的非同步方法吗?

如果多个线程访问非同步方法,该方法不会更改任何类字段,但有一些内部变量,安全吗?

人工示例:

public class Data{
// this hash map is filled before I start threads
protected Map<Integer, Spike> allSpikes = new HashMap<Integer, Spike>();

public HashMap returnBigSpikes(){
     Map<Integer, Spike> bigSpikes = new HashMap<Integer, Spike>();

     for (Integer i: allSpikes.keySet()){
         if (allSpikes.get(i).spikeSize > 100){
         bigSpikes.put(i,allSpikes.get(i));
         }
     }

     return bigSpikes;
}
}

从线程调用非同步方法 returnBigSpikes() 是否安全?

我现在明白,这样的用例可能非常危险,因为很难控制,数据(例如返回的 bigSpikes)不会被修改。但我已经像这样实现和测试了它,想知道我现在是否可以使用我的应用程序的结果,并稍后更改架构......

如果我同步这些方法会发生什么?应用程序的性能是否会降低至 1 个 CPU?如果是这样,我该如何正确设计并保持性能?

(我将大约 20-40 GB 的数据(日志消息)读取到主内存中,然后运行线程,这些线程需要遍历所有数据以找到其中的某些相关性;每个线程仅成为消息的一部分分析;但为了分析,线程应该将其部分的每条消息与数据中的许多其他消息进行比较;这就是为什么我首先决定允许线程在不同步的情况下读取数据)。

提前非常感谢您。

最佳答案

如果在所有线程启动之前填充 allSpikes,您可以通过将其另存为 unmodifiable map 来确保以后不会更改它。 。

假设 Spike 是不可变的,那么您的方法就可以完全安全地并发使用。

关于java - Java中线程访问非同步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15550704/

相关文章:

java - Java 中不可修改的 NavigableSet/NavigableMap?

Java远程类加载安全吗?

android - 如何从其他线程优雅地访问 Android View ?

java - 线程 - wait()

c++ - GSL+OMP : Thread safe random number generators in C++

java - 从后台线程异常设置 TextView 上的文本

java - 如何使用for循环循环二维数组?

c# - 我一直都在做错锁吗?

multithreading - 为什么从另一个线程访问 GUI 元素是错误的?

java - Google Map Api v2 不显示任何 map