【问题标题】:How does Java Threads workJava 线程是如何工作的
【发布时间】:2015-08-30 00:51:54
【问题描述】:

我是一名 Java 学习者,正在努力理解线程。

我希望下面的程序按顺序输出

线程开始运行方法再见

但我按顺序得到输出

Bye Thread started Run Method

这是我的代码:

public class RunnableThread
{
    public static void main(String[] args)
    {
        MyThread t1= new MyThread("Thread started");
        Thread firstThread= new Thread(t1);
        firstThread.start();
        System.out.println("Bye");
    }
}

class MyThread implements Runnable
{
    Thread t;
    String s= null;

    MyThread(String str)
    { 
      s=str;
    }

    public void run()
    {
      System.out.println(s);
      System.out.println("Run Method");
    }
}

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    在多线程代码中,无法保证哪个线程将以什么顺序运行。这是多线程的核心,不限于 Java。您可能会得到一次订单 t1, t2, t3,再一次得到 t3, t1, t2 等等。

    在您的情况下,有 2 个线程。一个是主线程,另一个是 firstThread。不确定哪个会先执行。

    【讨论】:

      【解决方案2】:

      这就是线程的全部意义——它们同时运行(如果你的处理器只有一个内核,它是伪同时的,但对程序员来说没有区别)。

      当您在 Thread 对象上调用 Thread.start() 方法时,它是相似的(但不一样,因为它正在启动一个线程,而不是一个进程,而前者更消耗资源)启动另一个java程序。所以firstThread.start() 开始与您的主线程(由您的 main 方法启动)并行运行。

      这一行启动一个主执行线程(如 zeroThread)

      public static void main(String[] args)
      

      您可以通过调用 Thread.sleep() 来引用它。

      这一行

      firstThread.start();
      

      启动另一个线程,但是为了引用它,您使用它的名称,但是您从与 firstThread 并行运行的主线程中引用它。 为了获得预期的输出,您可以加入这两个线程,这就像链接它们: 这样:

      public static void main(String[] args)
      {
          MyThread t1= new MyThread("Thread started");
          Thread firstThread= new Thread(t1);
          firstThread.start();
          firstThread.join();
          System.out.println("Bye");
      }
      

      join(),在 firstThread 上调用(由主线程)强制主线程等待直到 firstThread 完成运行(它将暂停执行下一个命令,即 System.out.println (“再见”);)。

      【讨论】:

        【解决方案3】:

        您似乎在寻找线程(可能不止一个)来运行,而main() 正在等待一切完成。 ExecutorService 提供了一种很好的管理方式——包括在时间阈值后退出的能力。

        import java.util.concurrent.*;                                                   
        
        class MyThread implements Runnable { // ... }                                    
        
        class MyProgram {                                                                
          public static void main(String[] args)                                         
          {                                                                              
            MyThread t1 = new MyThread();                                            
            MyThread t2 = new MyThread();                                            
            MyThread t3 = new MyThread();                                            
        
            // At this point, 3 threads teed up but not running yet                  
        
            ExecutorService es = Executors.newCachedThreadPool();                    
        
            es.execute(t1);                                                          
            es.execute(t2);                                                          
            es.execute(t3);                                                          
        
            // All three threads now running async                                   
        
            // Allow all threads to run to completion ("orderly shutdown")            
            es.shutdown();                                                           
        
            // Wait for them all to end, up to 60 minutes.  If they do not 
            // finish before then, the function will unblock and return false:          
            boolean finshed = es.awaitTermination(60, TimeUnit.MINUTES);             
        
            System.out.println("Bye");                                               
          }                                                                            
        }                                                                               
        

        【讨论】:

          【解决方案4】:

          没有指定 Java 线程习惯于运行的顺序。这适用于所有线程,包括“主”线程。

          如果你真的想看到它工作,试试:

          class RunnableThread
          {
              public static void main(String[] args)
              {
                  MyThread t1= new MyThread();
                  Thread firstThread= new Thread(t1);
                  firstThread.start();
                  System.out.println("Thread Main");
                  for(int i=1;i<=5;i++)
                  {
                      System.out.println("From thread Main i = " + i);
                  }
                  System.out.println("Exit from Main");
              }
          }
          
          class MyThread implements Runnable
          {
              public void run()
              {
                  System.out.println("Thread MyThread");
                  for(int i=1;i<=5;i++)
                  {
                      System.out.println("From thread MyThread i = " + i);
                  }
                  System.out.println("Exit from MyThread");
              }
          }
          

          【讨论】:

            【解决方案5】:

            当您启动一个线程时,它将与当前线程并行执行,因此没有保证执行顺序。

            尝试一些类似的东西:

            public class RunnableThread {
                static class MyThread implements Runnable {
                    Thread t;
                    String s= null;    
                    MyThread(String str) { 
                      s=str;
                    }
                    public void run() {
                      System.out.println(s);
                      System.out.println("Run Method");
                    }
                }
                public static void main(String[] args) {
                    MyThread t1= new MyThread("Thread started");
                    Thread firstThread= new Thread(t1);
                    firstThread.start();
                    boolean joined = false;
                    while (!joined)
                        try {
                            firstThread.join();
                            joined = true;
                        } catch (InterruptedException e) {}
                    System.out.println("Bye");
                }
            }
            

            【讨论】:

              【解决方案6】:

              不是线程启动顺序问题。因为您实际上只是启动一个线程

              这实际上更像是一个 API 调用 速度问题。

              基本上,您只有一个 println() 打印“再见”,只要 Thread.start() 返回就会调用它。 Thread.start() 返回 immediately after being called. 不等待 run() 调用完成。

              所以你在 "thread.start()" 之后进行 "println" 和线程初始化,并且 println 获胜。

              作为旁注,一般来说,您可能希望尽可能使用ExecutorServiceCallable,因为它们是更高级别、更新的 API。

              【讨论】:

              • thread.start() 是异步的吗? (即它立即返回而没有真正启动线程)
              • @Reek start() 在 run() 完成之前返回。在启动线程的操作系统级工作完成后返回。
              • 那么thread.start()返回后,有2个线程。他们现在还可以比赛吗?
              • 没说没有比赛。但这不是线程启动顺序问题。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-03-30
              • 2011-12-03
              • 1970-01-01
              • 1970-01-01
              • 2014-04-13
              相关资源
              最近更新 更多