java個人學習筆記16(多執行緒+extends Thread+implements Runnable)
1.多執行緒
程序:正在執行的應用程式在記憶體中分配的空間
執行緒:是程序中負責程式執行的執行單元,也稱執行路徑一個程序中至少有一個執行緒在負責該程序的執行
多執行緒技術:解決多部分程式碼同時執行的需求,合理使用cpu資源,提高使用者體驗。(微觀上序列,並未實際上提高效率)
多執行緒的執行是根據cpu的切換完成的,具有不確定性。
jvm中的多執行緒(至少2個):一個負責程式碼的執行,這個從main方法執行的執行緒稱為主執行緒。
一個負責垃圾回收(不定時)
每一個執行緒都有執行程式碼的內容,稱之為執行緒的任務。執行緒的任務都封裝在特定的區域中。
主執行緒執行的任務都定義在main方法中
垃圾回收執行緒(finalize)在收垃圾時會執行finalize()方法。
class Demo{ public void finalize(){//垃圾回收方法,即釋放資源。不保證該函式一定會被呼叫 System.out.println("demo recycle"); } } class FinalizeDemo{ public static void main(String[] args) { new Demo(); new Demo(); new Demo(); new Demo(); System.gc();//啟動垃圾回收器,不一定呼叫finalize(),由cpu切換造成的不確定性 System.out.println("Hello World!"); } }
2.建立多執行緒的兩種方法
1)繼承Thread類
繼承Thread
覆蓋run()
建立子類物件就是建立執行緒物件
呼叫Thread類中的start(),同時會呼叫run()
注意:start()開啟執行緒後,都會呼叫run(),所以run()中儲存的都是執行緒要執行的程式碼。
呼叫run()和呼叫start()的區別:
呼叫start()會開啟執行緒,並用開啟的執行緒去執行run()方法中的內容
呼叫run()不會開啟執行緒,執行run()方法中內容的是main執行緒
class Demo extends Thread { private String name; Demo(String name){ this.name = name; } public void show(){ for(int i = 1;i <= 10;i++) System.out.println(Thread.currentThread().getName()+"...."+name+"........"+i); } //Thread.currentThread()獲取當前執行執行緒的引用 //getName()獲取執行緒的名字 public void run(){ show(); }//覆蓋run() } class ThreadDemo { public static void main(String[] args) { Demo d1 = new Demo("Jack"); Demo d2 = new Demo("Tom"); d1.start(); d2.start(); for(int i = 1;i <= 10;i++) System.out.println(Thread.currentThread().getName()+"----"+"MainThread"+"......"+i); } }
2)實現Runnable介面
1)定義一個類實現Runnable
2)覆蓋Runnable介面中的run方法,將執行緒要執行的任務程式碼儲存到該方法中
3)通過Thread類建立執行緒物件,並將實現了Runnable介面的物件作為Thread類的建構函式的引數進行傳遞
4)呼叫Thread類的start方法,開啟執行緒
注意:此方法將執行緒物件和執行緒任務分開了
實現Runnable介面的好處:
1)避免了繼承Thread類的單繼承的侷限性
2)Runnable介面的出現更符合面向物件,將執行緒單獨進行物件的封裝
3)Runnable介面的出現,降低了執行緒物件和執行緒任務的耦合性
所以開發多用實現Runnable介面。
多執行緒的安全問題:
產生原因:
1)執行緒任務處理到共享資料
2)執行緒任務中有多條對共享資料的操作
解決思想:
互斥地訪問臨界資源
解決辦法:
同步程式碼塊(未操作共享資料的程式碼無需同步)
synchronized(object){
需要被同步的程式碼
}
同步的前提:
多執行緒在同步中必須使用同一個鎖(object)
class SaleTicket implements Runnable
{
private int tickets = 100;
Object obj = new Object();//synchronized(obj),相當於“鎖”
public void run(){
while(true){
synchronized(obj){//同步程式碼塊
if(tickets > 0){
try{
Thread.sleep(10);//執行緒停止執行10ms
}catch(InterruptedException e){}
System.out.println(Thread.currentThread().getName()+"...."+tickets--);
}
}
}
}
}
class TicketSystem
{
public static void main(String[] args)
{
SaleTicket t = new SaleTicket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
Thread t3 = new Thread(t);
Thread t4 = new Thread(t);
t1.start();
t2.start();
t3.start();
t4.start();
}
}