第一種方式:繼承Thread類
步驟:1、定義類繼承Thread
2、覆寫Threa類的run方法。 自定義代碼放在run方法中,讓線程運行
3、調用線程的star方法,
該線程有兩個作用:啟動線程,調用run方法。
代碼示例:
1 class Test extends Thread 2 { 3 //private String name; 4 Test(String name) 5 { 6 //this.name = name; 7 super(name); 8 } 9 public void run() 10 { 11 for(int x=0; x<60; x++) 12 { 13 System.out.println((Thread.currentThread()==this)+"..."+this.getName()+" run..."+x); //Thread.currentThread():獲取當前線程對象 14 } 15 } 16 17 } 18 19 20 class ThreadTest 21 { 22 public static void main(String[] args) 23 { 24 Test t1 = new Test("one---"); 25 Test t2 = new Test("two+++"); 26 t1.start(); 27 t2.start(); 28 // t1.run(); 29 // t2.run(); 30 31 for(int x=0; x<60; x++) 32 { 33 System.out.println("main....."+x); 34 } 35 } 36 }
第二種方式:實現Runnable接口
步驟:1、定義類實現Runnable接口
2、覆蓋Runnable接口中的run方法,運行的代碼放入run方法中。
3、通過Thread類建立線程對象。
4、將Runnable接口的子類對象作為實際參數傳遞給Thread類的構造函數。
因為,自定義的run方法所屬的對象是Runnable接口的子類對象。所以要讓線程去指定指定對象的run方法。就必須明確該run方法所屬對象
5、調用Thread類的start方法開啟線程並調用Runnable接口子類的run方法
代碼示例:賣票程序,多個窗口同時賣票
1 class Ticket implements Runnable 2 { 3 private int tick = 100; 4 public void run() 5 { 6 while(true) 7 { 8 if(tick>0) 9 { 10 System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--); 11 } 12 } 13 } 14 } 15 16 17 class TicketDemo 18 { 19 public static void main(String[] args) 20 { 21 22 Ticket t = new Ticket(); 23 24 Thread t1 = new Thread(t);//創建了一個線程; 25 Thread t2 = new Thread(t);//創建了一個線程; 26 Thread t3 = new Thread(t);//創建了一個線程; 27 Thread t4 = new Thread(t);//創建了一個線程; 28 t1.start(); 29 t2.start(); 30 t3.start(); 31 t4.start(); 32 } 33 }
兩種方式的區別:
第二種方式好處:避免了單繼承的局限性。比如當一個student類繼承了person類,再需繼承其他的類時就不能了,所以在定義線程時,建議使用第二種方式。
解決多線程安全性問題:1、同步代碼塊
2、同步函數:鎖為this
3、靜態同步函數: 鎖為Class對象:類名.class
