Java 为什么对象不能从参数传递到新线程内部

Java 为什么对象不能从参数传递到新线程内部,java,multithreading,Java,Multithreading,在下面的代码中,当我调用doSomethingCool(x)时我遇到了一个问题,无法获取myco.name的值;当它在线的侧面时。如何将其传递到线程内部 MyCustomObj x = new MyCustomObj(); x.name = "test"; doSomethingCool(x); protected void doSomethingCool(final MyCustomObj myco) { Thread t = new Thread() {

在下面的代码中,当我调用
doSomethingCool(x)时
我遇到了一个问题,无法获取myco.name的值;当它在线的侧面时。如何将其传递到线程内部

MyCustomObj x = new MyCustomObj();
x.name = "test";


doSomethingCool(x); 


    protected void doSomethingCool(final MyCustomObj myco) {
        Thread t = new Thread() {

            public void run() {

                  //Myco is null  why?
                  String sName = myco.name; ////Why wont the object Myco pass through to here?

            }
        };

        t.start();      
    }

您可能需要将MyCustomObj.name标记为volatile,以确保所有线程都看到相同的值

例如:


通常,如果需要将参数传递给线程,可以使用以下两种方法之一:

  • 创建如下自定义可运行文件:

    public class MyRunnable implements Runnable{
    
    private MyCustomObj obj;
    
    public MyRunnable( MyCustomObj obj) {
    
      this.obj = obj;
    
    }
    
    public void run() {
    
      System.out.println("Name:" + obj.name );
    
    }
    
    }

  • 然后

    MyCustomObj x = new MyCustomObj();
    x.name = "test";
    Thread t = new Thread(new MyRunnable(x));
    t.start();
    
    2.创建自定义线程,如下所示:

    public class MyThread extends Thread{
    
    private MyCustomObj obj;
    
    public MyThread( MyCustomObj obj) {
    
    this.obj = obj;
    
    }
    
    public void run() {
    
    System.out.println("Name:" + obj.name );
    
    }
    }
    
    然后

     MyThread t = new MyThread(x);
     t.start();
    

    希望这对您有所帮助

    您写得正确。这是调试器的问题

    我在Eclipse/Android插件中经常看到这种调试的胡说八道。有时重新启动IDE(eclipse)会有所帮助。有时我只需要重新启动模拟器。有一次,我不得不重新启动计算机(它是在Linux中)


    另外,将try/catch放在那里,并将断点放在catch中。

    您将获得该字符串的值。请参见下面的代码-

    public class Exct
    {
        Me m=new Me();
        String s;
        public static class Me
        {
            public String ht()
            {
                return "me";
            }
        }
    
        public static void main(String ... args)
        {
            Exct c=new Exct();
            try
            {
                System.out.println(c.call(c.m)+" in main");
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
        public String call(final Me m) throws Exception
        {
    
            Thread t=new Thread()
            {
                public void run()
                {
                    s=m.ht();
                    System.out.println(s+" in run");
    
                }
            };
            t.start();
            //System.out.println(s+" in run return ");
            //t.sleep(1);
            return s;
        }
    }
    
    这里是输出-

    主要为空 我跑了

    因为当t.start()执行时,它将搜索run方法,但由于java的多线程特性,同时执行return语句并返回null值

    现在,如果您想做任何可以等待线程直到run方法执行的事情,那么返回的值将是准确的。我们可以通过打开一段时间后执行的null但return的打印行来实现这一点,或者我们可以让线程睡眠1秒钟来完成剩余的工作,然后输出将是空的-

    我跑了 主要是我


    现在我没有任何其他解释,我会在找到任何其他好的解决方案时更新它。

    为什么
    异常e有一个空的catch块
    ?1) 您永远不应该只捕获所有异常。2) 您应该至少输出一些内容来指示发生了异常。您的问题是什么?就在这里。您能告诉我们MyCustomObj的代码吗?请显示堆栈跟踪。请确保在校准方法之前正确初始化。如果你说的是实际没有发生的事情,但你说的是你认为发生的事情。如果我打断它并添加一个手表,我可以在线程的一侧看到它为空。你知道为什么吗?保持volatile为变量不会将对象更改为not nullI我只能假设你正在运行的代码与你提供的代码不同,因为它看起来应该对我起作用。创建线程时存在“发生在之前”关系,因此线程将始终看到所有参数的正确值。不需要volatileOr#3,只需访问其作用域中的变量,这正是他正在做的事情。@hello World hello,如果确实如此,请编辑标记,将IDE名称(eclipse/netbeans/IntellijIdea…)和调试器放在那里。
    public class Exct
    {
        Me m=new Me();
        String s;
        public static class Me
        {
            public String ht()
            {
                return "me";
            }
        }
    
        public static void main(String ... args)
        {
            Exct c=new Exct();
            try
            {
                System.out.println(c.call(c.m)+" in main");
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
        public String call(final Me m) throws Exception
        {
    
            Thread t=new Thread()
            {
                public void run()
                {
                    s=m.ht();
                    System.out.println(s+" in run");
    
                }
            };
            t.start();
            //System.out.println(s+" in run return ");
            //t.sleep(1);
            return s;
        }
    }