線程實現方式。
並發與並行:
並發:多個任務交替執行 (一個人吃兩個饅頭,兩個交替啃)
並行:同時執行。(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->0main->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(); }
線程實現方式。