Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.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 - Fatal编程技术网

Java 如何在线程中保留和实例化对象

Java 如何在线程中保留和实例化对象,java,multithreading,Java,Multithreading,假如我有以下几点 public class Foo { private Map<Integer,SomeObject> myMap; public Foo() { this.myMap = new HashMap<Integer,SomeObject>(); } private class Runner implements Runnable { public void run() { SomeO

假如我有以下几点

public class Foo {
   private Map<Integer,SomeObject> myMap;
   public Foo() {
      this.myMap = new HashMap<Integer,SomeObject>();
   }

   private class Runner implements Runnable {
       public void run() {
            SomeObject someObj = new SomeObject();
            Foo.this.myMap.put(10,someObj);
            //'soObj' will always be null upon retrieval later...
       }   
   }
}
如果我创建一个Runnable类型为“Runner”的线程并启动该线程,它将运行。 在run方法中,我只需创建“SomeObject”的一个实例,并将其放置在外部类的映射中。 但是,当我稍后尝试从“myMap”获取值时,“SomeObject”实例将始终为空。我不明白为什么,因为我已经在映射“myMap”中放置了一个引用,该映射在线程完成后仍然存在于堆中。有办法吗


非常感谢

也许您应该看看java.util.concurrent中的FutureTask-它可以返回一个对象


也许您应该看看java.util.concurrent中的FutureTask,它可以返回一个对象


如果您是从一个线程写入而从另一个线程读取,则必须考虑并发访问和可见性。由于您的代码snipplet没有显示任何这方面的迹象,我想这可能就是问题所在。在任何情况下,你都必须先解决它,然后再深入挖掘问题

您必须执行某种类型的同步,如,或特殊的并发类,如。确保您熟悉这些技术,尤其是ConcurrentHashMap可能会很难处理,具体取决于您希望如何使用它


编辑:对于一个简单的同步映射,您可以从great Collections类中使用,但要注意这些映射上的迭代。有关详细信息,请参阅相应的javadoc。

如果您是从一个线程编写而从另一个线程读取,则必须考虑并发访问和可见性。由于您的代码snipplet没有显示任何这方面的迹象,我想这可能就是问题所在。在任何情况下,你都必须先解决它,然后再深入挖掘问题

您必须执行某种类型的同步,如,或特殊的并发类,如。确保您熟悉这些技术,尤其是ConcurrentHashMap可能会很难处理,具体取决于您希望如何使用它


编辑:对于一个简单的同步映射,您可以使用great Collections类,但是要注意这些映射上的迭代。有关详细信息,请参阅相应的javadoc。

这可能是对象实例化方式的问题。应该是:

    Foo foo = new Foo();
    Thread thread = new Thread(foo.new Runner());
    thread.start();

这可能是对象实例化方式的问题。应该是:

    Foo foo = new Foo();
    Thread thread = new Thread(foo.new Runner());
    thread.start();

不,它不会是空的。如果你认为你看到你还有其他问题要解决,那么好吧。我的逻辑中可能有什么遗漏。那么你是说当线程死亡时,'SomeObject'实例仍然在堆上,因为我在'myMap'中传递了对它的引用?换句话说,它不会被标记为垃圾收集?谢谢首先,你确定跑步者真的跑了吗?就像某个线程执行的那样?如果是这样,那么它会将对象放在映射中,这样就有了一条从最外层的Foo实例到映射到SomeObject的路径。然后,如果Foo仍然存在-在堆栈上或全局状态中有对它的引用-SomeObject将是可访问的,而不是GC'd。请不要像这样格式化问题中的代码。看见简短版本:只需将代码缩进4个空格,或使用Ctrl+K或单击{}按钮即可。对格式设置表示歉意。我不知道如何正确地做。是的,我确信跑步者确实跑了。我得深入挖掘,看看到底发生了什么。我有一种感觉,这可能与并发性有关,因为我知道HashMaps不是内部同步的……不,它不会为null。如果你认为你看到你还有其他问题要解决,那么好吧。我的逻辑中可能有什么遗漏。那么你是说当线程死亡时,'SomeObject'实例仍然在堆上,因为我在'myMap'中传递了对它的引用?换句话说,它不会被标记为垃圾收集?谢谢首先,你确定跑步者真的跑了吗?就像某个线程执行的那样?如果是这样,那么它会将对象放在映射中,这样就有了一条从最外层的Foo实例到映射到SomeObject的路径。然后,如果Foo仍然存在-在堆栈上或全局状态中有对它的引用-SomeObject将是可访问的,而不是GC'd。请不要像这样格式化问题中的代码。看见简短版本:只需将代码缩进4个空格,或使用Ctrl+K或单击{}按钮即可。对格式设置表示歉意。我不知道如何正确地做。是的,我确信跑步者确实跑了。我得深入挖掘,看看到底发生了什么。我有一种感觉,这可能与并发性有关,因为我知道HashMaps不是内部同步的…你是对的。。。这解决了我的问题。我正在实例化我的线程,就像一个新的线程…开始;我把它改为-threadt=newthreadfoo.newrunner;t、 开始;有什么区别?!嘿,我不知道这样的语法+1文档最后说:要实例化内部类,必须先实例化外部类。你是对的。。。
这解决了我的问题。我正在实例化我的线程,就像一个新的线程…开始;我把它改为-threadt=newthreadfoo.newrunner;t、 开始;有什么区别?!嘿,我不知道这样的语法+1文档最后说:要实例化内部类,必须先实例化外部类。