【问题标题】:How does java class method is allocated memory and executed in single threaded and multithreaded environment?java类方法如何在单线程和多线程环境中分配内存和执行?
【发布时间】:2016-10-01 19:32:56
【问题描述】:

我了解了方法是如何执行的,这就是我所理解的: 1)方法在方法区域中分配内存,并且只维护一个副本,该副本在类的所有实例中使用。 2)当从实例调用方法时,当前线程(单线程环境)说 main 被加载,然后堆栈加载通过实例调用的方法。例如:

main(String ags[])
{
   A a = new A();
   a.method();
}
// code of method
 method()
 {
   for(int i=0;i<25;i++)
   system.out.println(i);
 }

所以对于这个线程,它有自己的调用堆栈,然后在方法调用中,带有其局部变量的相同方法体被推送到主方法上方的同一个堆栈中。

现在基于上述理解,我不明白的是,在多线程环境中,如果我运行两个线程,相同的代码将如何表现 并且两者共享同一个实例。例如:

//My run method for myRunnable
run()
{
  a.method();
}

Thread one = new Thread(new myRunnable(a)); // object from above
Thread two= new Thread(new myRunnable(a));

现在当两个线程开始执行时,它们将拥有自己的调用堆栈。

这种情况下共享对象的方法将如何执行?

谢谢

【问题讨论】:

    标签: java multithreading callstack


    【解决方案1】:

    1) 方法在方法区域中分配内存,并且只维护一个副本,该副本在类的所有实例中使用>>这意味着方法实现的字节码每个实例只有一个。并且方法字节码的内存区域与对象的堆是分开的。

    当然,每个线程都有自己的堆栈,就像您解释的那样。

    【讨论】:

    • 是的,但我不明白的是,如果两个线程都在自己的堆栈中加载方法的副本,所以这意味着两者都应该打印自己的序列,比如从 1 到 25。输出是共享的,这意味着一个线程开始序列并一直到说 5 然后两个线程从那里拾取并从 6 开始到某个点说 10 然后一个从 10 开始。如果他们都有自己的堆栈会发生这种情况。
    • 不,这不应该发生。您是如何观察到这一点的?
    • 方法区是同步的,也是垃圾回收的。方法区同步的例子是加载一个新的类。如果两个线程要加载新的类,第一次尝试锁定方法区,类加载器启动并加载类,而其他方法正在等待。
    【解决方案2】:

    如果你有多个线程同时在同一个对象上运行同一个方法,你有以下情况:

    • 局部变量存储在每个线程的堆栈中。它们不共享,也不冲突。

    • 对象实例(this)及其所有字段(如this.foo)都存储在堆上。堆是共享的。为确保其正常工作,您必须酌情应用线程同步机制。

    • static 字段也是共享的,访问也必须协调

    在您的示例中,循环中的 i 是一个局部变量。两个线程将按顺序打印所有数字(但两个线程的输出以未定义的顺序交错)。

    【讨论】:

    • 是的,你的解释很有道理,但我在输出中找不到任何重复的数字。
    • 感谢大家的解释。
    【解决方案3】:

    好的,你走进一个房间。

    有人递给你一个剪贴板、一支铅笔和一个白板记号笔,然后 告诉您开始遵循写在某个 墙上的海报。

    另一面墙上有一块白板:它看起来像一个有行的电子表格 和列,以及写在单元格中的数字和单词。你的剪贴板有一个 一张纸,有更多的行和列,一些数字写在 铅笔中的一些单元格。

    这些说明一步一步地告诉您如何执行一些复杂的操作 计算。他们会说,

    ...
    Step 37: Copy the number from B5 on the whiteboard into J2 on your
             clipboard.
    Step 38: Add J2 through J7 on your clipboard, and write the result in J9.
    Step 39: If the result in J9 is greater than the value in whiteboard-C9,
             then go back to step 22, otherwise, go on to step 40.
    Step 40: Erase whiteboard-C9, and then copy the value from clipboard-J9
             into that location.
    ...
    

    剪贴板上有一个空间,您可以在其中编写自己的笔记。你可以 例如,使用它来跟踪您正在进行的步骤或其他任何事情 您需要记住才能完成工作。

    墙上还有其他海报,还有其他人,每个人都有 他/她自己的剪贴板。有些人正在听从指挥部的指示 与您相同的海报,其中一些正在阅读其他海报。 每个人都在同一个白板上读/写。

    每个人都按照自己的节奏前进。读相同的人 海报,因为你不一定和你在同一个步骤,因为每个 你的剪贴板上写着不同的初始数字,你甚至可能没有 以相同的顺序执行指令。

    这是一个简单的多线程计算模型: 墙是方法,白板是堆,人是线程, 你的剪贴板就是你的堆栈。

    这也大致类似于科学/工程计算的方式 在工业时代完成。从事这种工作的人是 称为“计算机”。

    如果你正在协调整个事情,是时候添加一个新的“线程”(即,当一个新的志愿者走进房间时),那么你需要给那个人他/她自己的剪贴板( stack),具有自己的初始值(参数),但您不给新人她/他自己的海报(方法):您只需将她/他指向已经在墙上的海报之一。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-23
      • 1970-01-01
      相关资源
      最近更新 更多