簡體   English   中英

Java Threads如何工作

[英]How does Java Threads work

我是一名Java學習者,試圖理解Threads。

我期待下面的程序輸出,順序

線程開始運行方法再見

但我得到了訂單中的輸出

再見線程啟動了運行方法

這是我的代碼:

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。 你可以得到一次t1,t2,t3,t3,t1,t2等等。

在你的情況下,有2個線程。 一個是主線程,另一個是firstThread。 尚未確定哪個將首先執行。

這是線程的全部內容 - 它們同時運行(如果你的處理器只有一個核心,它是偽同步的,但程序員沒有區別)。

當你在Thread對象上調用Thread.start()方法時,它是相似的(但不一樣,因為它啟動一個線程,而不是一個進程而且前者更耗費資源)同時啟動另一個java程序。 所以firstThread.start()開始運行你的主線程的paralel(由你的main方法啟動)。

這一行啟動一個主執行線程(如zeroThread)

public static void main(String[] args)

您可以通過調用Thread.sleep()來引用它。

這條線

firstThread.start();

啟動另一個線程,但為了引用它你使用它的名稱,但是你從主線程引用它,它運行paralel到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(“Bye”);)。

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");                                               
  }                                                                            
}                                                                               

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");
    }
}

不是線程啟動順序問題。 因為你真的只是開始一個線程

這實際上更像是API調用速度問題。

基本上,你有一個println()打印“bye”,一旦Thread.start()返回就會被調用。 Thread.start() 在被調用后立即返回 不等待run()調用完成。

所以你在“thread.start()”之后競爭“println”和線程初始化,並且println贏了。

作為旁注,通常,您可能希望盡可能使用ExecutorServiceCallable ,因為這些是更高級別的新API。

當您啟動一個線程時,它將與當前線程並行執行,因此無法保證執行順序。

嘗試一下:

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");
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM