11.多線程

11.多線程

1.理解程序、進程、線程的概念

程序可以理解為靜態的代碼

進程可以理解為執行中的程序。

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

2.如何創建java程序的線程(重點)

方式一:繼承於Thread類

class PrintNum extends Thread{
public void run(){
//子線程執行的代碼
for(int i = 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) {
PrintNum p1 = new PrintNum("線程1");
PrintNum p2 = 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(int i = 1;i <= 100;i++){
if(i % 2 == 0){
System.out.println(Thread.currentThread().getName() + ":" + i);
}
}
}
}
public class TestThread{
public static 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

比較哪個好?實現的方式較好。①解決了單繼承的侷限性。②如果多個線程有共享數據的話,建議使用實現方式,同時,共享

數據所在的類可以作為Runnable接口的實現類。

線程裡的常用方法:start() run() currentThread() getName() setName(String name) yield() join() sleep() isAlive()

getPriority() setPriority(int i); wait() notify() notifyAll()

3.線程的生命週期

11.多線程

4.線程的同步機制(重點、難點)

前提:如果我們創建的多個線程,存在著共享數據,那麼就有可能出現線程的安全問題:當其中一個線程操作共享數據時,還未操作完成,

另外的線程就參與進來,導致對共享數據的操作出現問題。

解決方式:要求一個線程操作共享數據時,只有當其完成操作完成共享數據,其它線程才有機會執行共享數據。

方式一:同步代碼塊:

synchronized(同步監視器){

//操作共享數據的代碼

}

注:1.同步監視器:俗稱鎖,任何一個類的對象都可以才充當鎖。要想保證線程的安全,必須要求所有的線程共用同一把鎖!

2.使用實現Runnable接口的方式創建多線程的話,同步代碼塊中的鎖,可以考慮是this。如果使用繼承Thread類的方式,慎用this!

3.共享數據:多個線程需要共同操作的變量。 明確哪部分是操作共享數據的代碼。

方式二:同步方法:將操作共享數據的方法聲明為synchronized。

比如:public synchronized void show(){ //操作共享數據的代碼}

注:1.對於非靜態的方法而言,使用同步的話,默認鎖為:this。如果使用在繼承的方式實現多線程的話,慎用!

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

總結:釋放鎖:wait();

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

死鎖:不同的線程分別佔用對方需要的同步資源不放棄,都在等待對方放棄自己需要的同步資源,就形成了線程的死鎖

死鎖是我們在使用同步時,需要避免的問題!

5.線程的通信:如下的三個方法必須使用在同步代碼塊或同步方法中!

wait():當在同步中,執行到此方法,則此線程“等待”,直至其他線程執行notify()的方法,將其喚醒,喚醒後繼續其wait()後的代碼

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


分享到:


相關文章: