为什么main方法中的代码在java中的其他Thread之前执行

时间:2018-03-11 22:14:55

标签: java multithreading

我有Main类和main方法。我创建两个线程我注意到主线程中的代码在创建Threads之前执行。我期待的是同时运行它。为什么main方法的代码执行Threads的berofe代码?

Main.class:

def index
  @events = Event.all # or whatever you query will look like, maybe filter after month
  respond_to do |format|
    format.html { render 'index' }
    format.json { render json: @events }
  end
end

} }

NewThread.class

public class Main extends Thread {
public static void main(String[] args) {
    NewThread thread = new NewThread("Thread1");
    NewThread thread2 = new NewThread("Thread2");
    for (int i = 0; i <3 ; i++) {
        System.out.println("From main thread");
    }
    thread.start();
    thread2.start();       

}

输出:

public class NewThread extends Thread{

public NewThread(String name) {
    this.setName(name);
}
public void run() {
    int clientnumber = 1;
    while(clientnumber!= 3) {
        System.out.println("server sent data to client: " + getName());
        clientnumber++;
    }
}

3 个答案:

答案 0 :(得分:3)

  

为什么main方法的代码在Threads的代码之前执行?

简单地说,因为它可以。

当您start()一个线程时,可以安排父线程或子线程下次运行。或者他们可能同时安排。或者可以安排一个完全不同的线程。

Java语言和运行时系统不保证线程调度顺序。此外,对于不同的执行平台 1 ,线程调度行为可能不同;例如取决于您拥有多少核心。

(为什么?因为,这就是本机线程调度在典型操作系统上的工作原理.Java无法对抗这种情况并仍使用本机线程。使用用户空间线程和线程调度存在严重的性能问题.Sun放弃了接近几十年前。)

你是如何解决这个问题的?

  • 不要对计划以及执行线程的顺序做出假设。

  • 如果您的应用程序确实需要一个线程在另一个之前运行,请使用其中一个并发原语或类来明确地实现它。 (但要注意,通过强制一个线程在另一个线程之前运行,你会降低有效并发性。)

在您的示例中,问题基本上是您的期望不正确。一旦你调整了你的期望,这已不再是一个问题。

1 - 在给定平台上,行为可能是可重复的,特别是在像您这样的小/简单示例中。但话说回来,如果你在系统负载很重的情况下运行测试,它可以更改。记住:不保证!

答案 1 :(得分:2)

其他线程的执行以.start()方法开头 - 在

中将此方法调用后,将信息循环打印到控制台。

编辑:这些行在新线程的行之前打印,因为打印3行到控制台可能比在其他线程中执行循环然后打印更快。在编辑完问题之后 - 看看所有三个线程(包括包含main()的线程)如何在同一时间工作并查看打印行的顺序差异 - 我建议你尝试其中一个以下方法来看待差异:

  1. 尝试在main()开始新线程之后和main()中打印到控制台之前执行耗时的操作(您可以自己考虑该操作或尝试Thread.sleep(1000)中列出的其中一项操作{3}}或
  2. 尝试在每个线程中使用语句打印到控制台来增加循环次数(甚至可能减少到几千次) - 您将看到所有线程同时工作,或者
  3. 在开始新线程之后和{{1}打印行之前,只需在main()中调用main()(或更高的数字作为参数 - 它是您希望当前线程休眠的毫秒数) }}。

答案 2 :(得分:1)

NewThread线程必须在它开始执行之前启动。只有在main()处理完循环后才启动两个线程。你想要的可能是:

new NewThread("Thread1").start();
new NewThread("Thread2").start(); 
for (int i = 0; i <3 ; i++) {
    System.out.println("From main thread");
}

然而,由JVM和OS来安排线程。在main()有机会运行之前,您仍然可能会先观察NewThread执行。