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

nam*_*olk 112 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;

    }

}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

当线程1获得机会时,它会从暂停的第1部分恢复执行吗?

当所有五个线程之间共享一个Clstest.testStaticMethod并且相同时,它Clstest.testStaticMethod是如何发生的?

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

sel*_*lig 190

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

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

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

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

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

  • 你有它.只是为了澄清一些观点 - 首先,线程的调度方式不受Java的控制.我在这里谈论Sun的Hotspot JVM.JVM将Java线程映射到OS线程,OS决定运行哪些线程.正如您所说,在单核心机器上,操作系统一次只能运行一个,但在多核机器中,它可能同时运行多个.其次,线程暂时不知道它何时被暂停,它所拥有的唯一信息是它的程序指针(指向代码的指针)和堆栈,它们被保存并完全恢复原样. (6认同)
  • 那么,在多核处理器环境中可能有多个线程同时运行相同的代码不是吗?在单处理器环境中,在给定时间只有一个线程在运行.(多个线程在它们之间共享时间.)因此,当线程调度程序从当前排除线程(A)到线程(B)的机会时,线程(A)如何从暂停的位置恢复?我的意思是它如何知道简历点?是不是因为"每个线程都有一个指向代码的指针,指向他们当前运行的代码位?" 如你所说? (3认同)
  • 确切地说,当线程共享堆中的内容(非本地)时,干扰只会发生并且可能发生,但不一定会发生。有几种不同的发生干扰的方式,这取决于代码不同部分之间的依赖性。我不确定您的示例,因为缺少一些细节。也许您是在指一个潜在的问题,线程A和B都读取一个共享值,然后都基于读取的值对其进行更新。这是一场数据竞赛。 (2认同)

Han*_*ant 66

它会进入睡眠状态吗?

No, running a thread does not affect other threads as long as they don't intentionally synchronize with each other. If you have more than one processor core, all recent machines do, those threads are likely to execute at the exact same time. That gets to be bit less likely when you start 5 threads since your machine might not have enough cores. The operating system is forced to choose between them, giving them each some time to run. The job of the thread scheduler. A thread will then not be in a "sleep" state, it is simply paused and waiting for the thread scheduler to give it a chance to run. It will resume where it was interrupted by the scheduler.

Is there any possibility to interchange the inFileStr sent by multiple threads?

There is no such possibility, threads have their own stack so any method argument and local variable will be unique for each thread. Using a string furthermore guarantees that these threads cannot interfere with each other since strings are immutable.

There's no such guarantee if the argument is a reference to another kind of mutable object. Or if the method itself uses variables that are static or references to objects on the heap. Synchronization is required when a thread modifies the object and another thread reads it. The lock keyword in the C# language is the boilerplate way to implement such required synchronization. The fact that the method is static does not mean such synchronization is never required. Just less likely since you don't have to worry about threads accessing the same object (sharing this).

  • 糟糕,从未见过[java]标签.足够近. (3认同)