在调用某个线程的start()方法后,主线程是否立即获得控制权?

sha*_*182 20 java multithreading

例如 :

public class Example1 {

    public static void main(String[] args) {
        Loop loop = new Loop();
        loop.start(); //printing "Before start"
        System.out.println("After start");
    }
}
Run Code Online (Sandbox Code Playgroud)

可以是loop在执行打印"After Start"的最后一行之前运行方法结束的情况吗?

pax*_*blo 41

一旦你开始多线程,你最好放弃你对线程运行顺序的所有假设.

如果它很重要,你可以使用同步操作,但没有它们,所有的赌注都会被取消.


Umb*_*ndi 11

是的,您无法控制JVM如何执行/调度线程.

如果你想引入某种排序(按顺序执行两个线程),最简单的方法就是使用LockJava提供的一个对象.


MSB*_*MSB 11

您基本上是在询问Java中的线程安全性(至少这是我从问题中理解的).正如早先的答案之一已经说明的那样,在运行多个线程时放弃关于执行顺序的任何假设是个好主意.

然而(!),可以使用设计原则和批判性思维来模拟您的应用程序,使得多线程不会发生不希望的副作用.

对于初学者,你可以阅读这篇关于设计对象启动 的文章.文章的要点是你应该把你的类想象成finite state machines.如果您不知道它们是什么:finite state machines在一组状态下操作(因此名称).

这个想法是,当你在状态(A),您可以定义的行为,这种特定的状态可以执行:(A) -> (B), (A) -> (C) 我可以从状态进入(A)到状态(B)(C),但不说明(D)(它必须存在)这种心态是很重要的,了解你的应用CAN在做任何给定的情况.(精细状态机维基百科)

一旦你理解了这一点,你就可以进入 修复:

有三种方法可以使对象线程安全:

  • 同步关键部分
  • 让它一成不变
  • 使用线程安全的包装器

每种方法都有自己的优点/缺点,这些优点/缺点在Java文档中有解释:

希望这可以让您更好地了解在创建多线程应用程序时可能遇到的复杂问题.

  • 语气并不是以光顾的方式表达,但已经适当注意到,我重写了答案.我希望现在以更好的方式呈现信息. (3认同)

rat*_*eak 6

如果我在线程上添加一个连接和一些打印语句,那么可以解释一些特性.

public class Example1 {

    public static void main(String[] args) {
        Loop loop = new Loop();
        System.out.println("Before start");
        loop.start(); //printing "Before start"
        System.out.println("After start");
        loop.join();
        System.out.println("After join");
    }
}
Run Code Online (Sandbox Code Playgroud)

"开始之前"将始终loop.run()执行之前打印.

完成后将始终打印"加入后" loop.run().

"开始后"无法保证何时打印相对于loop.run(); 它可以在之前,它可以在之后,它可以在执行期间与loop.run()中的print语句交错.

如果您确实需要保证,那么您需要其他同步实用程序,如锁和信号量.