Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.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_Garbage Collection_Java Threads_Java Memory Model - Fatal编程技术网

局部变量中引用的Java实例变量。内存、线程安全和终结

局部变量中引用的Java实例变量。内存、线程安全和终结,java,garbage-collection,java-threads,java-memory-model,Java,Garbage Collection,Java Threads,Java Memory Model,我有一个类MyClass,它有一个带有变量的方法——OtherClass的一个实例,如下所示 public class Myclass{ public void meth1(){     OtherClass other = new OtherClass(); other.perform();       } } public class OtherClass{ private Map<String, String> ops = new HashMa

我有一个类MyClass,它有一个带有变量的方法——OtherClass的一个实例,如下所示

public class Myclass{ 
   public void meth1(){
 
  OtherClass other = new OtherClass();  
    other.perform();
     
    }

}

public class OtherClass{

private Map<String, String> ops = new HashMap<>();

public void perform(){

  // put/ remove values in ops 
    }

} 
公共类Myclass{
公共图书馆1({
 
  OtherClass other=新的OtherClass();
其他。执行();
     
}
}
公共类其他类{
私有映射操作=新的HashMap();
公开执行{
//在ops中放置/删除值
}
} 
这是一个多线程环境 当线程执行meth1()方法时,映射在哪里创建?成堆?声明为实例变量的映射是否存在线程安全问题wrt。 当局部变量被垃圾收集时,我假设map也被垃圾收集。如果我错了,请改正

注意:我知道在多线程环境中使用实例变量时会出现数据损坏
不过,这与场景略有不同,将在堆上创建
其他类
对象,并在堆栈上创建对该对象的引用。由于
堆栈限制
,此代码是完全线程安全的。只有当对象的状态在多个线程之间共享时,才会出现线程安全问题。由于该对象只能由调用该方法的线程访问,因此它不是共享的。一旦堆栈弹出,对象将被垃圾收集。

将在堆上创建
OtherClass
对象,并在堆栈上创建对该对象的引用。由于
堆栈限制
,此代码是完全线程安全的。只有当对象的状态在多个线程之间共享时,才会出现线程安全问题。由于该对象只能由调用该方法的线程访问,因此它不是共享的。一旦堆栈弹出,对象将被垃圾收集

当线程执行meth1()方法时,映射在哪里创建? 成堆

对。使用
newwhatever()
创建的所有内容都存储在堆中,
OtherClass
实例及其
HashMap
(因为其初始化包括
newhashmap()
表达式)。每次执行
newwhere()
,堆上都会有一个全新的实例

声明为实例的映射是否存在线程安全问题 变数

不,不在你的例子中。只有当多个线程访问同一个
OtherClass
实例时,线程安全才可能成为一个问题。在您的例子中,每个执行线程都会创建其各自的
OtherClass
实例(在局部变量
other
中),只使用该实例,而不会将其分发给其他线程可能看到它的任何地方

当本地变量被垃圾收集时,我假设map是 还收集垃圾

是的,只要不添加将地图分发给软件其他部分的代码

当实例不再被任何“活动”变量/参数/对象/引用时,它们将被垃圾收集。。。在您的例子中,
ops
HashMap仅由其所包含的
OtherClass
实例的
ops
字段引用(存储)。因此,当这个实例不再可访问时,映射也将变得不可访问,从而准备进行垃圾收集

一句话:垃圾收集不会发生在某些东西变得不可访问的同一时刻,它是由一些精心设计的优化算法安排的。你唯一能确定的是它会在你的内存用完之前发生

注意:我知道当我们有实例变量时,会出现数据损坏 但在多线程环境中,这略有不同 情景

事实恰恰相反:如果没有实例或类字段,就不会遇到线程安全/数据损坏问题

真实情况是:如果在多线程设置中使用实例或类字段,则必须小心。但例如,只读实例字段(仅在构造函数中设置且以后不会更改的字段)通常是安全的

当线程执行meth1()方法时,映射在哪里创建? 成堆

对。使用
newwhatever()
创建的所有内容都存储在堆中,
OtherClass
实例及其
HashMap
(因为其初始化包括
newhashmap()
表达式)。每次执行
newwhere()
,堆上都会有一个全新的实例

声明为实例的映射是否存在线程安全问题 变数

不,不在你的例子中。只有当多个线程访问同一个
OtherClass
实例时,线程安全才可能成为一个问题。在您的例子中,每个执行线程都会创建其各自的
OtherClass
实例(在局部变量
other
中),只使用该实例,而不会将其分发给其他线程可能看到它的任何地方

当本地变量被垃圾收集时,我假设map是 还收集垃圾

是的,只要不添加将地图分发给软件其他部分的代码

当实例不再被任何“活动”变量/参数/对象/引用时,它们将被垃圾收集。。。在您的例子中,
ops
HashMap仅由其所包含的
OtherClass
实例的
ops
字段引用(存储)。因此,当这个实例不再可访问时,映射也将变得不可访问,从而准备进行垃圾收集

一句话:垃圾收集不会发生在某些东西变得不可访问的同一时刻,它是由一些精心设计的优化算法安排的。你唯一能确定的是它会在你的内存用完之前发生

注意:我知道当我们有实例变量时,会出现数据损坏 在多个