国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

黑馬程序員----java基礎:多線程

2019-11-14 21:57:39
字體:
來源:轉載
供稿:網友
黑馬程序員----java基礎:多線程

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

------Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! -------

  如果一次只完成一個事情,還是比較容易實現的,但事實上很多事情都是同時執行的,java為了模擬這種狀態,引入了線程機制。

當程序同時完成多個事情時,就是所謂的多線程程序。

  在一個時刻,單核的cpu只能運行一個程序。而我們看到的同時運行效果,只是cpu在多個進程間做著快速的隨機切換動作。

  所以說多線程解決了多部分同時運行的問題,但是線程太多的話肯定會影響效率。

  首先老規矩一張圖來展現我們本次要介紹的內容:

一、實現方式

實現線程的方式一共有兩種---繼承Thread類和實現Runnable接口。

1、繼承Thread類。

a、定義類繼承Thread。

b、復寫Thread中的run方法。

c、創建定義類的實例對象。

d、調用start方法啟動線程。

class TestThread extends Thread            // a、定義類繼承Thread。{    public void run()                    //b、復寫Thread中的run方法。    {        for (int x = 0; x < 50 ;x++ )        {            System.out.

2、實現runnable接口

  a、定義類實現Runnable的接口。

b、覆蓋Runnable接口中的run方法。

c、通過Thread類創建線程對象。

d、調用start方法啟動線程。

class TestThread implements Runnable            //a、定義類實現Runnable的接口。{public void run()// b、覆蓋Runnable接口中的run方法。{for (int x = 0; x < 50 ;x++ ){System.out.println(Thread.currentThread()+"++++++"+x);}}}class Demo{public static void main(String[] args) {TestThread d = new TestThread();Thread t1 = new Thread(d);Thread t2 = new Thread(d);//c、通過Thread類創建線程對象。t1.start();     //d、調用start方法啟動線程。t2.start();}}

3、實現Runnable接口的優勢

  實際開發中,我們經常使用第二種方式做多線程,它的優勢在于

  a、避免了按照面向對象的思想將任務封裝成對象。

  b、避免了java單繼承的局限性。

二、線程的生命周期

線程具有生命周期,其各個生命周期的關系如下圖。

三、線程安全

  實際開發中,使用多線程的情況有很多,比如火車站售票系統,當有多個線程做取票動作時,假設此時只有一張票,一線程將票售出,此時二線程完成了判斷是否有票動作,并得出票數大于0結論。此時執行售票就會產生負數。

1、安全問題產生的原因

  a、多個線程在操縱共享數據

  b、操縱共享數據的代碼有多條。

2、解決辦法--同步

  將多條操作共享數據的線程代碼封裝起來,當有線程執行這些代碼時候,其他線程不可參與。

  a、同步代碼塊

  

synchronized(obj){  //需要同步的代碼}

  b、同步函數

public synchronized void show()  {          //需要同步的代碼}     

3、同步函數和同步代碼塊的區別

  同步函數的鎖是this

  同步代碼塊的鎖是任意的(也可以是this)

  實際開發中建議用同步代碼塊。

4、同步的利弊

好處:解決了多線程的安全問題。

弊端:多個線程需要判斷鎖,較為消耗資源。

5、靜態函數代碼塊

  如果同步函數被靜態修飾后,使用的鎖是什么呢?設計模式中的單例模式給大家展示。

//懶漢式class Single{    private static Single s = null;    private Single(){}    public static Single getInstance()    {        if(s == null)        {            synchronized(Single.class)    //靜態方法寫---類名.class            {                if(s==null)                    s = new Single();            }        }        return s;    }}

四、線程間通信

線程間的通信其實就是多個線程共享同一個資源。

class  ResorceDemo{    public static void main(String[] args)     {        Resorce r = new Resorce();        Input in = new Input(r);        Output out = new Output(r);        Thread t1 = new Thread(in);        Thread t2 = new Thread(out);        t1.start();        t2.start();    }}class Resorce //定義一個資源{    String name;    String sex;    boolean flag = false;}class Input implements Runnable//寫入資源{    Resorce r;    Input(Resorce r)    {        this.r = r;    }    public void run()//復寫run方法    {        int x = 0;//x相當于一個標志.        while (true)        {            synchronized(r)            {                if (r.flag == true)                {                    try                    {                        r.wait();                     }                    catch (InterruptedException e)                    {                    }                                    }                else                {                    if (x==0)                    {                        r.name = "mike";                        r.sex = "nan";                    }                    else                    {                        r.name = "傻妞";                        r.sex = "妞妞妞妞i牛i牛ii牛";                    }                    r.flag = true;                    r.notify();//喚醒                }                    x = (x+1)%2;//x在0和1之間相互交替.                                                            }            }    }}class Output implements Runnable//讀取資源{    Resorce r;    Output(Resorce r)    {        this.r = r;    }    public void run()    {        while (true)//無限循環        {            synchronized(r)            {                if (r.flag == false)                {                    try                    {                        r.wait();                     }                    catch (InterruptedException e)                    {                    }                                    }                else                {                    System.out.println(r.name + "..."+r.sex);                    r.flag = false;                    r.notify();                }                            }                    }    }}

五、常見操作方法

1,wait(): 讓線程處于凍結狀態,被wait的線程會被存儲到線程池中。2,notify():喚醒線程池中一個線程(任意).3,notifyAll():喚醒線程池中的所有線程。4,setPriority():設置優先級5,yield():暫停當前線程,讓其他線程執行。

當然,這些常見的操作方法在API中都可以查到,這不是我要說的重點,下面來對這些方法做一下比較。

(1)wait 和 sleep 區別?

  1,wait可以指定時間也可以不指定。 sleep必須指定時間。

  2,在同步中時,對cpu的執行權和鎖的處理不同。 wait:釋放執行權,釋放鎖。 sleep:釋放執行權,不釋放鎖。

(2)wait(),notify(),notifyAll(),用來操作線程為什么定義在了Object類中?

a,這些方法存在與同步中。

b,使用這些方法時必須要標識所屬的同步的鎖。同一個鎖上wait的線程,只可以被同一個鎖上的notify喚醒。

c,鎖可以是任意對象,所以任意對象調用的方法一定定義Object類中。

六、總結

多線程本身也是比較復雜的問題,要完全理解它還需要時間,所謂孰能生巧,這些知識還是要多看多練多去實踐才能真正掌握。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阿克陶县| 乌鲁木齐县| 霍州市| 阜城县| 佛教| 镇远县| 肥城市| 秭归县| 保亭| 浦东新区| 安义县| 大宁县| 山东| 石渠县| 濮阳县| 巴中市| 西和县| 商丘市| 通州区| 濮阳市| 江川县| 东乡族自治县| 台安县| 琼海市| 枞阳县| 黔西县| 凌海市| 灵石县| 七台河市| 蓝田县| 武汉市| 青龙| 安塞县| 正安县| 内黄县| 德清县| 茌平县| 襄樊市| 理塘县| 台前县| 陈巴尔虎旗|