1. 程式人生 > >java se基礎-多執行緒

java se基礎-多執行緒

多執行緒

1.理解程式、程序、執行緒的概念

         程式可以理解為靜態的程式碼

         程序可以理解為執行中的程式

         執行緒可以理解為程序的進一步細分,程式的一條執行路徑

2.如何建立java程式的執行緒(重點)

方式一:繼承Thread類

class PrintNum extends Thread{

         public void run(){

                   //子執行緒執行的程式碼

                   for(inti = 1;i <= 100;i++){

                            if(i% 2 == 0){

                                     System.out.println(Thread.currentThread().getName()+ ":" + i);

                            }

                   }

         }

         public PrintNum(String name){

                   super(name);

         }

}

 

 

public class TestThread {

         public static void main(String[] args) {

                   Print Nump1 = new PrintNum("執行緒1");

                   Print Nump2 = new PrintNum("執行緒2");

                   p1.setPriority(Thread.MAX_PRIORITY);//10

                   p2.setPriority(Thread.MIN_PRIORITY);//1

                   p1.start();

                   p2.start();

         }

}

方式二:實現Runnable介面

class SubThread implements Runnable{

         public void run(){

                   //子執行緒執行的程式碼

                   for(inti = 1;i <= 100;i++){

                            if(i% 2 == 0){

                                     System.out.println(Thread.currentThread().getName()+":"+ i);

                            }

                   }

         }

}

public class TestThread{

         publicstatic void main(String[] args){

                   SubThread s = new SubThread();

                   Thread  t1 = new Thread(s);

                   Thread  t2 = new Thread(s);

 

                   t1.setName("執行緒1");

                   t2.setName("執行緒2");

                  

                   t1.start();

                   t2.start();

         }

}

兩種方式的對比:聯絡:class Thread implements Runnable

                              比較哪個好?實現的方式較好. a.解決了單繼承的侷限性 b.如果多個執行緒有共享資料的話,建議使用實現方式.同時,共享資料所在的類可以作為Runnable介面的實現類

執行緒裡的常用方法:start()   run()   currentThread()    getName()  setName(String name)   yield()   join()   sleep()  isAlive()   wait()   notify()  notifyAll()

3.執行緒的生命週期

4.執行緒的同步機制(重點)

前提:如果我們建立的多個執行緒,存在著共享資料,那麼就可能出現執行緒的安全問題:當其中一個執行緒操作共享資料時,還未操作完成,另外的執行緒就參與進來,導致對共享資料的操作出現問題.

解決方式:要求一個執行緒操作共享資料時,只有當其完成操作共享資料,其他執行緒才有機會執行共享資料.

方式一:同步程式碼塊:

                   synchronized(同步監視器){

                            //操作共享資料的程式碼

                   }

                   注:1.同步監視器:俗稱鎖,任何一個類的物件都可以充當鎖.要想保證執行緒的安全,必須要求所有的執行緒共用同一把鎖!

                      2.使用實現Runnable介面的方式建立多執行緒的話,同步程式碼塊中的鎖,可以考慮是this,如果使用繼承Thread類的方式,慎用this!

                      3.共享資料:多個執行緒需要共同操作的變數.明確哪部分是操作共享資料的程式碼.

方式二:同步方法:將操作共享資料的方法宣告為synchronized.

         比如:publicsynchronized void show(){//操作共享資料的程式碼}

         注:1.對於非靜態的方法而言,使用同步的話,預設鎖為:this,如果使用在繼承的方式實現多執行緒的話,慎用!

            2.對於靜態的方法,如果使用同步,預設的鎖為:當前類本身.以前類本身.以單例的懶漢式為例.  Class clazz = Singleton.class

總結:釋放鎖: wait();

         不釋放鎖:sleep()   yield()  suspend() (過時,可能導致死鎖)

死鎖:不同的執行緒分別佔用對方需要的同步資源不放棄,都在等待對方放棄自己需要的同步資源,就形成了執行緒的死鎖.死鎖是我們在使用同步時,需要避免的問題!

5.執行緒的通訊:如下的三個方法必須使用在同步程式碼塊或同步方法中!

wait():當在同步中,執行到此方法,則此執行緒"等待",直至其他執行緒執行notity()的方法,將其喚醒,喚醒後繼續其wait()後的程式碼

notify()/notifyAll():在同步中,執行到此方法,則喚醒其他的某一個或所有的被wait的執行緒.