併發與並行: 併發:多個任務交替執行 (一個人吃兩個饅頭,兩個交替啃) 並行:同時執行。(n個人吃n個饅頭) 速度快些。 線程與進程: 進程:進入到記憶體中的程式叫進程。 線程: 主線程: 執行主方法(main)的線程 單線程程式:Java程式中只有一個線程,從main方法開始,從上到下依次執行。 J ...
併發與並行:
併發:多個任務交替執行 (一個人吃兩個饅頭,兩個交替啃)
並行:同時執行。(n個人吃n個饅頭) 速度快些。
線程與進程:
進程:進入到記憶體中的程式叫進程。
線程:
主線程:
執行主方法(main)的線程
單線程程式:Java程式中只有一個線程,從main方法開始,從上到下依次執行。
JVM執行main方法,main方法會進入棧記憶體,
然後JVM找到操作系統開闢一條main方法通向cpu的執行路徑,
cpu就可以通過這個路徑執行main方法,這個路徑叫main(主)線程。
多線程:
java程式屬於搶占式調度,哪個線程高,哪個線程就優先執行,同一級別隨機執行。
創建多線程程式的第一種方式:
java.lang.Thread 類:是描述線程的類,想實現多線程程式,就必須繼承該類。
實現步驟:
1、創建Thread類的子類。
2、子類重寫run方法, 來設置線程任務。
3、創建子類對象,調用start()方法,開啟新的線程,執行run方法。
結果是:兩個線程併發執行。
public class MyThread extends Thread { @Override public void run() { for (int i=0;i<3;i++){ System.out.println("run->"+i); } } }
public class ThreadDemo { public static void main(String[] args) { MyThread myThread=new MyThread(); myThread.start(); for (int i=0;i<3;i++){ System.out.println("main->"+i); }
main->0
run->0
main->1
run->1
main->2
run->2 } }
多線程運行原理:
new MyThread的時候,又開闢了一條通向cpu的新路徑,來執行run方法。
此時,對cpu而言,就有了兩條執行路徑。
main線程和新線程一起搶奪cpu的執行權。
多線程記憶體分析:
開始執行程式時,開闢一塊棧記憶體,main方法入棧。
此時,如果直接調用run方法的話,也是在這塊棧記憶體執行run(),也就是仍然
是main線程程式(單線程)程式。
而如果調用的是start(),會另外開闢一塊棧空間,run()入棧執行。
Thread類的常用方法:
獲取線程名稱:
1、Thread類的方法,getName();
2、獲取當前正在執行的線程 static Thread currentThead(),然後用getName();
第一種:
public class MyThread extends Thread { @Override public void run() { System.out.println(getName()); } }
public static void main(String[] args) { new MyThread().start(); new MyThread().start(); //Thread-0 // Thread-1 }
第二種:
public static void main(String[] args) { System.out.println(Thread.currentThread().getName()); //main } }
設置線程名稱:
1、void setName(String name) 2、設置帶參構造函數
sleep方法:
public static void sleep(Long ...) :使當前正在執行的線程以指定毫秒暫停。
public static void main(String[] args) { for (int i=0;i<5;i++){ System.out.println(i); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }
創建多線程程式的第二種方式:
實現Runnable介面:
java.lang.Runnable. 實現類必須定義run的無參方法。
java.lang.Thread 類的構造方法:
1、Thread(Runnable target) 分配新的Thread對象。
2、Thread(Runnable target,String name)。
實現步驟:
1、創建Runnable介面的實現類。
2、重寫run方法,設置線程任務。
3、創建實現類的對象,用含有Runnable介面的構造函數創建Thread類對象。
4、用start方法,開啟新線程執行run();
public class RunnableClass implements Runnable { @Override public void run() { for (int i=0;i<5;i++){ System.out.println( Thread.currentThread().getName() +"->"+i ); } } }
public static void main(String[] args) { RunnableClass runnable=new RunnableClass(); Thread thread=new Thread(runnable); thread.start(); for (int i=0;i<5;i++){ System.out.println( Thread.currentThread().getName() +"->"+i ); } }
兩種實現多線程方法的區別:
實現Runnable介面實現多線程的好處:
1、避免單繼承的局限性:
繼承了Thread類就不能繼承其他類了,而使用介面的方式還可以繼承其他類。
2、增強程式的擴展性,降低了程式的耦合性(解耦):
用實現Runnable介面的方式,把設置線程任務和開啟線程進行分離(解耦 )
匿名內部類實現多線程:
作用:
簡化代碼,把實現類實現介面,重寫方法,創建實現類方法統一完成。
格式: new 父類/介面(){重寫方法};
public static void main(String[] args) { new Thread() { @Override public void run() { for (int i=0;i<5;i++){ System.out.println(currentThread().getName()); } } }.start(); new Thread(new Runnable() { @Override public void run() { for (int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName()); } } }).start(); }