java中多线程环境中的静态方法行为

时间:2013-06-27 12:26:52

标签: java multithreading static-methods

有一个简单的愚蠢问题困扰着我并在脑海中提出了几个论点。 我想抛弃以下问题的所有疑虑。

class Clstest{

    public static String testStaticMethod(String inFileStr) {

        // section 0

        // section 1

        // do something with inFileStr

        // section 2

        // section 3

        return inFileStr;

    }

}

假设有五个线程同时执行对Clstest.testStaticMethod("arg-n")的调用。

线程1调用Clstest.testStaticMethod("arg-1")

当线程1在第1部分中时,线程2调用Clstest.testStaticMethod("arg-2")

那么线程1会发生什么?它会进入睡眠状态吗?

当线程1有机会从第1节暂停执行时会恢复执行吗?

如果在所有五个线程之间共享一个Clstest.testStaticMethod且相同的Clstest.testStaticMethod,会发生什么情况?

是否有可能交换多个线程发送的inFileStr

2 个答案:

答案 0 :(得分:185)

Hans Passant的回答很好。但是我想我会尝试在一个稍微简单的层面上解释一下,遇到这个并且对Java来说很新的人。这就是..

java中的内存分为两类 - 堆和堆栈。堆是所有对象都存在的地方,堆栈是线程工作的地方。每个线程都有自己的堆栈,无法访问其他堆栈。每个线程还有一个指向代码的指针,指向它们当前正在运行的代码位。

当一个线程开始运行一个新方法时,它会将该方法中的参数和局部变量保存在自己的堆栈中。其中一些值可能是指向堆上对象的指针。如果两个线程同时运行相同的方法,则它们的代码指针都指向该方法,并在其堆栈上拥有自己的参数和局部变量副本。如果堆栈上的东西指向堆上的相同对象,它们只会相互干扰。在这种情况下,可能会发生各种各样的事情。但正如汉斯指出的那样,字符串是不可改变的(不能改变)所以如果这是唯一被“共享”的对象,我们就是安全的。

这么多线程可以运行相同的方法。它们可能不会同时运行 - 它取决于您的机器上有多少核心,因为JVM将Java线程映射到OS线程,这些线程被调度到硬件线程上。因此,在没有使用复杂的同步机制的情况下,您几乎无法控制这些线程交错的方式。

请注意,睡眠是线程对自身的影响。

答案 1 :(得分:64)

  

它会进入睡眠状态吗?

不,运行线程不会影响其他线程,只要它们不会故意彼此同步即可。如果您有多个处理器核心,所有最近的计算机都可以,那么这些线程可能会在同一时间执行。由于您的机器可能没有足够的内核,因此当您启动5个线程时,这种可能性会降低一些。操作系统被迫在它们之间进行选择,每个都给它们一些时间来运行。线程调度程序的工作。一个线程将不会处于“休眠”状态,它只是暂停并等待线程调度程序给它一个运行的机会。它将在调度程序中断的地方恢复。

  

是否有可能交换多个线程发送的inFileStr?

没有这种可能性,线程有自己的堆栈,因此任何方法参数和局部变量对于每个线程都是唯一的。使用字符串还可以保证这些线程不会互相干扰,因为字符串是不可变的。

如果参数是对另一种可变对象的引用,则没有这样的保证。或者,如果方法本身使用静态变量或对堆上对象的引用。当线程修改对象而另一个线程读取它时,需要同步。 C#语言中的 lock 关键字是实现此类所需同步的样板方法。该方法 static 的事实并不意味着永远不需要这种同步。不太可能,因为您不必担心线程访问同一个对象(共享 this )。