Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java中访问非同步方法的线程_Java_Multithreading_Thread Safety_Thread Synchronization - Fatal编程技术网

Java中访问非同步方法的线程

Java中访问非同步方法的线程,java,multithreading,thread-safety,thread-synchronization,Java,Multithreading,Thread Safety,Thread Synchronization,我能解释一下线程和同步在Java中是如何工作的吗 我想写一个高性能的应用程序。在这个应用程序中,我将文件中的数据读入一些嵌套类,这些类基本上是HashMap的核心部分 数据读取完成后,我启动线程,这些线程需要遍历数据并对其执行不同的检查。但是,线程永远不会更改数据 如果我可以保证(或者至少尝试保证;)我的线程不会更改数据,我可以使用它们调用包含数据的对象的非同步方法吗 如果多个线程访问非同步方法,该方法不会更改任何类字段,但有一些内部变量,那么它安全吗 人工示例: public class Da

我能解释一下线程和同步在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;
}
}
公共类数据{
//此哈希映射在我启动线程之前填充
protected Map allSpikes=new HashMap();
公共HashMap returnbigspecks(){
Map bigspeakes=新HashMap();
for(整数i:allSpikes.keySet()){
如果(所有穗粒数。获得(i)。穗粒大小>100){
大钉子。放(i,所有钉子。得到(i));
}
}
返回大尖峰;
}
}
从线程调用非同步方法returnBigSpikes()安全吗

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

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

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


事先非常感谢。

你的计划应该可以很好地执行。您不需要
同步
读取,只需写入


但是,如果将来您希望缓存
大峰值
,以便所有线程都获得相同的映射,那么您需要更加小心同步。

您的计划应该可以正常工作。您不需要
同步
读取,只需写入


但是,如果将来您希望缓存
大峰值
,以便所有线程都获得相同的映射,那么您需要更加小心同步。

如果您使用,它将为您完成所有同步工作。它更好,然后围绕普通HashMap进行同步

如果您使用,它将为您完成所有同步工作。它更好,然后围绕普通HashMap进行同步

由于在启动线程之前已初始化所有Spikes,因此是安全的。只有当线程写入资源而其他线程从中读取时,并发问题才会出现

由于在启动线程之前已初始化所有Spikes,因此是安全的。只有当线程写入资源而其他线程从中读取时,并发问题才会出现

如果在所有线程开始之前填充了
allSpikes
,则可以通过将其保存为


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

如果在所有线程开始之前填充了
allSpikes
,您可以通过将其保存为


假设
Spike
是不可变的,那么您的方法将是完全安全的,可以同时使用。

一般来说,如果您有一组线程,您可以保证只有一个线程会修改一个资源,而其他线程只会读取该资源,那么对该资源的访问就不需要同步。在您的示例中,每次调用returnBigSpikes()方法时,它都会创建bigSpikes hashmap的一个新的本地副本,因此尽管您正在创建一个hashmap,但它对每个线程都是唯一的,因此没有同步问题。

通常,如果您有一组线程,您可以保证只有一个线程将修改资源,其余线程将只读取该资源,那么对该资源的访问不需要同步。在您的示例中,每次调用returnBigSpikes()方法时,它都会创建bigSpikes hashmap的一个新的本地副本,因此尽管您正在创建一个hashmap,但它对每个线程都是唯一的,因此没有同步问题。

只要任何实际上是不可变的(例如使用final关键字)并且您使用不可修改的映射,一切都很好

我建议提供以下不可修改的数据:

public class UnmodifiableData {
     final Map<Integer,Spike>  bigSpikes;
     public UnmodifiableData(Map<Integer,Spike> bigSpikes) {
         this.bigSpikes = Collections.unmodifiableMap(new HashMap<>(bigSpikes));
     }
     ....
公共类不可修改数据{
最终地图大尖峰;
公共不可修改数据(映射大峰值){
this.bigspecks=Collections.unmodifiableMap(新HashMap(bigspecks));
}
....

}

只要任何事实上是不可变的(例如使用final关键字),并且使用不可修改的映射,一切都很好

我建议提供以下不可修改的数据:

public class UnmodifiableData {
     final Map<Integer,Spike>  bigSpikes;
     public UnmodifiableData(Map<Integer,Spike> bigSpikes) {
         this.bigSpikes = Collections.unmodifiableMap(new HashMap<>(bigSpikes));
     }
     ....
公共类不可修改数据{
最终地图大尖峰;
公共不可修改数据(映射大峰值){
this.bigspecks=Collections.unmodifiableMap(新HashMap(bigspecks));
}
....

}

一次有多个线程访问
returnbigspecks
吗?是。这不是一个真实的示例,但我的应用程序已经是这样工作的。我认为您的代码在不使用同步的情况下可以安全工作。
returnbigspecks
一次被多个线程访问吗?是的。这不是一个真实的例子,但我的应用程序已经像这样工作了。我认为您的代码在不使用同步的情况下可以安全工作。…+1提到Spike必须是我