日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java多线程学习

發布時間:2025/3/20 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


本文主要講了java中多線程的使用方法、線程同步、線程數據傳遞、線程狀態及相應的一些線程函數用法、概述等。在這之前,首先讓

? ? ? ?
我們來了解下在操作系統中進程和線程的區別:

  

進程:每個進程都有獨立的代碼和數據空間(進程上下文),進程間的切換會有較大的開銷,一個進程包含1--n個線程。(進程是資源分配的最小單位)

  線程:同一類線程共享代碼和數據空間,每個線程有獨立的運行棧和程序計數器(PC),線程切換開銷小。(線程是cpu調度的最小單位)

  線程和進程一樣分為五個階段:創建、就緒、運行、阻塞、終止。

  多進程是指操作系統能同時運行多個任務(程序)。

  多線程是指在同一程序中有多個順序流在執行。

java中要想實現多線程,有兩種手段,一種是繼續Thread類,另外一種是實現Runable接口.(其實準確來講,應該有三種,還有一種是實現Callable接口,并與Future、線程池結合使用,此文這里不講這個,有興趣看這里Java并發編程與技術內幕:Callable、Future、FutureTask、CompletionService?)

一、擴展java.lang.Thread類

這里繼承Thread類的方法是比較常用的一種,如果說你只是想起一條線程。沒有什么其它特殊的要求,那么可以使用Thread.(筆者推薦使用Runable,后頭會說明為什么)。下面來看一個簡單的實例

[java]view plaincopy
  • package?com.multithread.learning;??
  • /**?
  • ?*@functon?多線程學習?
  • ?*@author?林炳文?
  • ?*@time?2015.3.9?
  • ?*/??
  • class?Thread1?extends?Thread{??
  • ????private?String?name;??
  • ????public?Thread1(String?name)?{??
  • ???????this.name=name;??
  • ????}??
  • ????public?void?run()?{??
  • ????????for?(int?i?=?0;?i?<?5;?i++)?{??
  • ????????????System.out.println(name?+?"運行??:??"?+?i);??
  • ????????????try?{??
  • ????????????????sleep((int)?Math.random()?*?10);??
  • ????????????}?catch?(InterruptedException?e)?{??
  • ????????????????e.printStackTrace();??
  • ????????????}??
  • ????????}??
  • ?????????
  • ????}??
  • }??
  • public?class?Main?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????Thread1?mTh1=new?Thread1("A");??
  • ????????Thread1?mTh2=new?Thread1("B");??
  • ????????mTh1.start();??
  • ????????mTh2.start();??
  • ??
  • ????}??
  • ??
  • }??
  • 輸出:

    A運行? :? 0
    B運行? :? 0
    A運行? :? 1
    A運行? :? 2
    A運行? :? 3
    A運行? :? 4
    B運行? :? 1
    B運行? :? 2
    B運行? :? 3
    B運行? :? 4

    再運行一下:

    A運行? :? 0
    B運行? :? 0
    B運行? :? 1
    B運行? :? 2
    B運行? :? 3
    B運行? :? 4
    A運行? :? 1
    A運行? :? 2
    A運行? :? 3
    A運行? :? 4
    說明: 程序啟動運行main時候,java虛擬機啟動一個進程,主線程main在main()調用時候被創建。隨著調用MitiSay的兩個對象的start方法,另外兩個線程也啟動了,這樣,整個應用就在多線程下運行。 注意:start()方法的調用后并不是立即執行多線程代碼,而是使得該線程變為可運行態(Runnable),什么時候運行是由操作系統決定的。 從程序運行的結果可以發現,多線程程序是亂序執行。因此,只有亂序執行的代碼才有必要設計為多線程。 Thread.sleep()方法調用目的是不讓當前線程獨自霸占該進程所獲取的CPU資源,以留出一定時間給其他線程執行的機會。 實際上所有的多線程代碼執行順序都是不確定的,每次執行的結果都是隨機的。

    但是start方法重復調用的話,會出現java.lang.IllegalThreadStateException異常。

    [java]view plaincopy
  • Thread1?mTh1=new?Thread1("A");??
  • Thread1?mTh2=mTh1;??
  • mTh1.start();??
  • mTh2.start();??

  • 輸出:

    Exception in thread "main" java.lang.IllegalThreadStateException
    ?? ?at java.lang.Thread.start(Unknown Source)
    ?? ?at com.multithread.learning.Main.main(Main.java:31)

    A運行? :? 0
    A運行? :? 1
    A運行? :? 2
    A運行? :? 3
    A運行? :? 4

    二、實現java.lang.Runnable接口

    采用Runnable也是非常常見的一種,我們只需要重寫run方法即可。下面也來看個實例。

    [java]view plaincopy
  • /**?
  • ?*@functon?多線程學習?
  • ?*@author?林炳文?
  • ?*@time?2015.3.9?
  • ?*/??
  • package?com.multithread.runnable;??
  • class?Thread2?implements?Runnable{??
  • ????private?String?name;??
  • ??
  • ????public?Thread2(String?name)?{??
  • ????????this.name=name;??
  • ????}??
  • ??
  • ????@Override??
  • ????public?void?run()?{??
  • ??????????for?(int?i?=?0;?i?<?5;?i++)?{??
  • ????????????????System.out.println(name?+?"運行??:??"?+?i);??
  • ????????????????try?{??
  • ????????????????????Thread.sleep((int)?Math.random()?*?10);??
  • ????????????????}?catch?(InterruptedException?e)?{??
  • ????????????????????e.printStackTrace();??
  • ????????????????}??
  • ????????????}??
  • ??????????
  • ????}??
  • ??????
  • }??
  • public?class?Main?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????new?Thread(new?Thread2("C")).start();??
  • ????????new?Thread(new?Thread2("D")).start();??
  • ????}??
  • ??
  • }??
  • 輸出:

    C運行? :? 0
    D運行? :? 0
    D運行? :? 1
    C運行? :? 1
    D運行? :? 2
    C運行? :? 2
    D運行? :? 3
    C運行? :? 3
    D運行? :? 4
    C運行? :? 4

    說明: Thread2類通過實現Runnable接口,使得該類有了多線程類的特征。run()方法是多線程程序的一個約定。所有的多線程代碼都在run方法里面。Thread類實際上也是實現了Runnable接口的類。 在啟動的多線程的時候,需要先通過Thread類的構造方法Thread(Runnable target) 構造出對象,然后調用Thread對象的start()方法來運行多線程代碼。 實際上所有的多線程代碼都是通過運行Thread的start()方法來運行的。因此,不管是擴展Thread類還是實現Runnable接口來實現多線程,最終還是通過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程編程的基礎。

    三、Thread和Runnable的區別

    如果一個類繼承Thread,則不適合資源共享。但是如果實現了Runable接口的話,則很容易的實現資源共享。

    總結:

    實現Runnable接口比繼承Thread類所具有的優勢:

    1):適合多個相同的程序代碼的線程去處理同一個資源

    2):可以避免java中的單繼承的限制

    3):增加程序的健壯性,代碼可以被多個線程共享,代碼和數據獨立

    4):線程池只能放入實現Runable或callable類線程,不能直接放入繼承Thread的類


    提醒一下大家:main方法其實也是一個線程。在java中所以的線程都是同時啟動的,至于什么時候,哪個先執行,完全看誰先得到CPU的資源。

    java中,每次程序運行至少啟動2個線程。一個是main線程,一個是垃圾收集線程。因為每當使用java命令執行一個類的時候,實際上都會啟動一個JVM,每一個jVM實習在就是在操作系統中啟動了一個進程。

    四、線程狀態轉換

    下面的這個圖非常重要!你如果看懂了這個圖,那么對于多線程的理解將會更加深刻!


    1、新建狀態(New):新創建了一個線程對象。 2、就緒狀態(Runnable):線程對象創建后,其他線程調用了該對象的start()方法。該狀態的線程位于可運行線程池中,變得可運行,等待獲取CPU的使用權。 3、運行狀態(Running):就緒狀態的線程獲取了CPU,執行程序代碼。 4、阻塞狀態(Blocked):阻塞狀態是線程因為某種原因放棄CPU使用權,暫時停止運行。直到線程進入就緒狀態,才有機會轉到運行狀態。阻塞的情況分三種: (一)、等待阻塞:運行的線程執行wait()方法,JVM會把該線程放入等待池中。(wait會釋放持有的鎖) (二)、同步阻塞:運行的線程在獲取對象的同步鎖時,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中。 (三)、其他阻塞:運行的線程執行sleep()或join()方法,或者發出了I/O請求時,JVM會把該線程置為阻塞狀態。當sleep()狀態超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉入就緒狀態。(注意,sleep是不會釋放持有的鎖) 5、死亡狀態(Dead):線程執行完了或者因異常退出了run()方法,該線程結束生命周期。

    五、線程調度

    線程的調度

    1、調整線程優先級:Java線程有優先級,優先級高的線程會獲得較多的運行機會。 Java線程的優先級用整數表示,取值范圍是1~10,Thread類有以下三個靜態常量: [plain]view plaincopy
  • static?int?MAX_PRIORITY??
  • ??????????線程可以具有的最高優先級,取值為10。??
  • static?int?MIN_PRIORITY??
  • ??????????線程可以具有的最低優先級,取值為1。??
  • static?int?NORM_PRIORITY??
  • ??????????分配給線程的默認優先級,取值為5。??

  • Thread類的setPriority()和getPriority()方法分別用來設置和獲取線程的優先級。 每個線程都有默認的優先級。主線程的默認優先級為Thread.NORM_PRIORITY。 線程的優先級有繼承關系,比如A線程中創建了B線程,那么B將和A具有相同的優先級。 JVM提供了10個線程優先級,但與常見的操作系統都不能很好的映射。如果希望程序能移植到各個操作系統中,應該僅僅使用Thread類有以下三個靜態常量作為優先級,這樣能保證同樣的優先級采用了同樣的調度方式。 2、線程睡眠:Thread.sleep(long millis)方法,使線程轉到阻塞狀態。millis參數設定睡眠的時間,以毫秒為單位。當睡眠結束后,就轉為就緒(Runnable)狀態。sleep()平臺移植性好。 3、線程等待:Object類中的wait()方法,導致當前的線程等待,直到其他線程調用此對象的 notify() 方法或 notifyAll() 喚醒方法。這個兩個喚醒方法也是Object類中的方法,行為等價于調用 wait(0) 一樣。 4、線程讓步:Thread.yield() 方法,暫停當前正在執行的線程對象,把執行機會讓給相同或者更高優先級的線程。 5、線程加入:join()方法,等待其他線程終止。在當前線程中調用另一個線程的join()方法,則當前線程轉入阻塞狀態,直到另一個進程運行結束,當前線程再由阻塞轉為就緒狀態。 6、線程喚醒:Object類中的notify()方法,喚醒在此對象監視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的,并在對實現做出決定時發生。線程通過調用其中一個 wait 方法,在對象的監視器上等待。 直到當前的線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作為鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。類似的方法還有一個notifyAll(),喚醒在此對象監視器上等待的所有線程。 注意:Thread中suspend()和resume()兩個方法在JDK1.5中已經廢除,不再介紹。因為有死鎖傾向。

    六、常用函數說明

    ①sleep(long millis):?在指定的毫秒數內讓當前正在執行的線程休眠(暫停執行)

    ②join():指等待t線程終止。

    使用方式。

    join是Thread類的一個方法,啟動線程后直接調用,即join()的作用是:“等待該線程終止”,這里需要理解的就是該線程是指的主線程等待子線程的終止。也就是在子線程調用了join()方法后面的代碼,只有等到子線程結束了才能執行。

    [java]view plaincopy
  • Thread?t?=?new?AThread();?t.start();?t.join();??
  • 為什么要用join()方法

    在很多情況下,主線程生成并起動了子線程,如果子線程里要進行大量的耗時的運算,主線程往往將于子線程之前結束,但是如果主線程處理完其他的事務后,需要用到子線程的處理結果,也就是主線程需要等待子線程執行完成之后再結束,這個時候就要用到join()方法了。

    不加join。
    [java]view plaincopy
  • /**?
  • ?*@functon?多線程學習,join?
  • ?*@author?林炳文?
  • ?*@time?2015.3.9?
  • ?*/??
  • package?com.multithread.join;??
  • class?Thread1?extends?Thread{??
  • ????private?String?name;??
  • ????public?Thread1(String?name)?{??
  • ????????super(name);??
  • ???????this.name=name;??
  • ????}??
  • ????public?void?run()?{??
  • ????????System.out.println(Thread.currentThread().getName()?+?"?線程運行開始!");??
  • ????????for?(int?i?=?0;?i?<?5;?i++)?{??
  • ????????????System.out.println("子線程"+name?+?"運行?:?"?+?i);??
  • ????????????try?{??
  • ????????????????sleep((int)?Math.random()?*?10);??
  • ????????????}?catch?(InterruptedException?e)?{??
  • ????????????????e.printStackTrace();??
  • ????????????}??
  • ????????}??
  • ????????System.out.println(Thread.currentThread().getName()?+?"?線程運行結束!");??
  • ????}??
  • }??
  • ??
  • public?class?Main?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????System.out.println(Thread.currentThread().getName()+"主線程運行開始!");??
  • ????????Thread1?mTh1=new?Thread1("A");??
  • ????????Thread1?mTh2=new?Thread1("B");??
  • ????????mTh1.start();??
  • ????????mTh2.start();??
  • ????????System.out.println(Thread.currentThread().getName()+?"主線程運行結束!");??
  • ??
  • ????}??
  • ??
  • }??
  • 輸出結果:
    main主線程運行開始!
    main主線程運行結束!
    B 線程運行開始!
    子線程B運行 : 0
    A 線程運行開始!
    子線程A運行 : 0
    子線程B運行 : 1
    子線程A運行 : 1
    子線程A運行 : 2
    子線程A運行 : 3
    子線程A運行 : 4
    A 線程運行結束!
    子線程B運行 : 2
    子線程B運行 : 3
    子線程B運行 : 4
    B 線程運行結束!
    發現主線程比子線程早結束

    加join
    [java]view plaincopy
  • public?class?Main?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ????????System.out.println(Thread.currentThread().getName()+"主線程運行開始!");??
  • ????????Thread1?mTh1=new?Thread1("A");??
  • ????????Thread1?mTh2=new?Thread1("B");??
  • ????????mTh1.start();??
  • ????????mTh2.start();??
  • ????????try?{??
  • ????????????mTh1.join();??
  • ????????}?catch?(InterruptedException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????????try?{??
  • ????????????mTh2.join();??
  • ????????}?catch?(InterruptedException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????????System.out.println(Thread.currentThread().getName()+?"主線程運行結束!");??
  • ??
  • ????}??
  • ??
  • }??

  • 運行結果:
    main主線程運行開始!
    A 線程運行開始!
    子線程A運行 : 0
    B 線程運行開始!
    子線程B運行 : 0
    子線程A運行 : 1
    子線程B運行 : 1
    子線程A運行 : 2
    子線程B運行 : 2
    子線程A運行 : 3
    子線程B運行 : 3
    子線程A運行 : 4
    子線程B運行 : 4
    A 線程運行結束!
    主線程一定會等子線程都結束了才結束

    ③yield():暫停當前正在執行的線程對象,并執行其他線程。
    Thread.yield()方法作用是:暫停當前正在執行的線程對象,并執行其他線程。 ?? ? ???yield()應該做的是讓當前運行線程回到可運行狀態,以允許具有相同優先級的其他線程獲得運行機會。因此,使用yield()的目的是讓相同優先級的線程之間能適當的輪轉執行。但是,實際中無法保證yield()達到讓步目的,因為讓步的線程還有可能被線程調度程序再次選中。 結論:yield()從未導致線程轉到等待/睡眠/阻塞狀態。在大多數情況下,yield()將導致線程從運行狀態轉到可運行狀態,但有可能沒有效果。可看上面的圖。
    [cpp]view plaincopy
  • /**?
  • ?*@functon?多線程學習?yield?
  • ?*@author?林炳文?
  • ?*@time?2015.3.9?
  • ?*/??
  • package?com.multithread.yield;??
  • class?ThreadYield?extends?Thread{??
  • ????public?ThreadYield(String?name)?{??
  • ????????super(name);??
  • ????}??
  • ???
  • ????@Override??
  • ????public?void?run()?{??
  • ????????for?(int?i?=?1;?i?<=?50;?i++)?{??
  • ????????????System.out.println(""?+?this.getName()?+?"-----"?+?i);??
  • ????????????//?當i為30時,該線程就會把CPU時間讓掉,讓其他或者自己的線程執行(也就是誰先搶到誰執行)??
  • ????????????if?(i?==30)?{??
  • ????????????????this.yield();??
  • ????????????}??
  • ????????}??
  • ??????
  • }??
  • }??
  • ??
  • public?class?Main?{??
  • ??
  • ????public?static?void?main(String[]?args)?{??
  • ??????????
  • ????????ThreadYield?yt1?=?new?ThreadYield("張三");??
  • ????????ThreadYield?yt2?=?new?ThreadYield("李四");??
  • ????????yt1.start();??
  • ????????yt2.start();??
  • ????}??
  • ??
  • }??

  • 運行結果:

    第一種情況:李四(線程)當執行到30時會CPU時間讓掉,這時張三(線程)搶到CPU時間并執行。

    第二種情況:李四(線程)當執行到30時會CPU時間讓掉,這時李四(線程)搶到CPU時間并執行。

    sleep()和yield()的區別
    ??????? sleep()和yield()的區別):sleep()使當前線程進入停滯狀態,所以執行sleep()的線程在指定的時間內肯定不會被執行;yield()只是使當前線程重新回到可執行狀態,所以執行yield()的線程有可能在進入到可執行狀態后馬上又被執行。
    ??????? sleep?方法使當前運行中的線程睡眼一段時間,進入不可運行狀態,這段時間的長短是由程序設定的,yield?方法使當前線程讓出?CPU?占有權,但讓出的時間是不可設定的。實際上,yield()方法對應了如下操作:先檢測當前是否有相同優先級的線程處于同可運行狀態,如有,則把?CPU??的占有權交給此線程,否則,繼續運行原來的線程。所以yield()方法稱為“退讓”,它把運行機會讓給了同等優先級的其他線程
    ?????? 另外,sleep?方法允許較低優先級的線程獲得運行機會,但?yield()??方法執行時,當前線程仍處在可運行狀態,所以,不可能讓出較低優先級的線程些時獲得?CPU?占有權。在一個運行系統中,如果較高優先級的線程沒有調用?sleep?方法,又沒有受到?I\O?阻塞,那么,較低優先級線程只能等待所有較高優先級的線程運行結束,才有機會運行。

    ④setPriority():?更改線程的優先級。

        MIN_PRIORITY = 1
    ?   ???NORM_PRIORITY = 5
    ????????? ?MAX_PRIORITY = 10

    用法:
    Thread4 t1 = new Thread4("t1"); Thread4 t2 = new Thread4("t2"); t1.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY);
    ⑤interrupt():不要以為它是中斷某個線程!它只是線線程發送一個中斷信號,讓線程在無限等待時(如死鎖時)能拋出拋出,從而結束線程,但是如果你吃掉了這個異常,那么這個線程還是不會中斷的!

    ⑥wait()

    Obj.wait(),與Obj.notify()必須要與synchronized(Obj)一起使用,也就是wait,與notify是針對已經獲取了Obj鎖進行操作,從語法角度來說就是Obj.wait(),Obj.notify必須在synchronized(Obj){...}語句塊內。從功能上來說wait就是說線程在獲取對象鎖后,主動釋放對象鎖,同時本線程休眠。直到有其它線程調用對象的notify()喚醒該線程,才能繼續獲取對象鎖,并繼續執行。相應的notify()就是對對象鎖的喚醒操作。但有一點需要注意的是notify()調用后,并不是馬上就釋放對象鎖的,而是在相應的synchronized(){}語句塊執行結束,自動釋放鎖后,JVM會在wait()對象鎖的線程中隨機選取一線程,賦予其對象鎖,喚醒線程,繼續執行。這樣就提供了在線程間同步、喚醒的操作。Thread.sleep()與Object.wait()二者都可以暫停當前線程,釋放CPU控制權,主要的區別在于Object.wait()在釋放CPU同時,釋放了對象鎖的控制。

    ??? 單單在概念上理解清楚了還不夠,需要在實際的例子中進行測試才能更好的理解。對Object.wait(),Object.notify()的應用最經典的例子,應該是三線程打印ABC的問題了吧,這是一道比較經典的面試題,題目要求如下:

    ??? 建立三個線程,A線程打印10次A,B線程打印10次B,C線程打印10次C,要求線程同時運行,交替打印10次ABC。這個問題用Object的wait(),notify()就可以很方便的解決。代碼如下:

    [java]view plaincopy
  • /**?
  • ?*?wait用法?
  • ?*?@author?DreamSea??
  • ?*?@time?2015.3.9??
  • ?*/??
  • package?com.multithread.wait;??
  • public?class?MyThreadPrinter2?implements?Runnable?{?????
  • ????????
  • ????private?String?name;?????
  • ????private?Object?prev;?????
  • ????private?Object?self;?????
  • ????
  • ????private?MyThreadPrinter2(String?name,?Object?prev,?Object?self)?{?????
  • ????????this.name?=?name;?????
  • ????????this.prev?=?prev;?????
  • ????????this.self?=?self;?????
  • ????}?????
  • ????
  • ????@Override????
  • ????public?void?run()?{?????
  • ????????int?count?=?10;?????
  • ????????while?(count?>?0)?{?????
  • ????????????synchronized?(prev)?{?????
  • ????????????????synchronized?(self)?{?????
  • ????????????????????System.out.print(name);?????
  • ????????????????????count--;????
  • ??????????????????????
  • ????????????????????self.notify();?????
  • ????????????????}?????
  • ????????????????try?{?????
  • ????????????????????prev.wait();?????
  • ????????????????}?catch?(InterruptedException?e)?{?????
  • ????????????????????e.printStackTrace();?????
  • ????????????????}?????
  • ????????????}?????
  • ????
  • ????????}?????
  • ????}?????
  • ????
  • ????public?static?void?main(String[]?args)?throws?Exception?{?????
  • ????????Object?a?=?new?Object();?????
  • ????????Object?b?=?new?Object();?????
  • ????????Object?c?=?new?Object();?????
  • ????????MyThreadPrinter2?pa?=?new?MyThreadPrinter2("A",?c,?a);?????
  • ????????MyThreadPrinter2?pb?=?new?MyThreadPrinter2("B",?a,?b);?????
  • ????????MyThreadPrinter2?pc?=?new?MyThreadPrinter2("C",?b,?c);?????
  • ?????????????
  • ?????????????
  • ????????new?Thread(pa).start();??
  • ????????Thread.sleep(100);??//確保按順序A、B、C執行??
  • ????????new?Thread(pb).start();??
  • ????????Thread.sleep(100);????
  • ????????new?Thread(pc).start();?????
  • ????????Thread.sleep(100);????
  • ????????}?????
  • }????

  • 輸出結果:

    ABCABCABCABCABCABCABCABCABCABC

    ?????先來解釋一下其整體思路,從大的方向上來講,該問題為三線程間的同步喚醒操作,主要的目的就是ThreadA->ThreadB->ThreadC->ThreadA循環執行三個線程。為了控制線程執行的順序,那么就必須要確定喚醒、等待的順序,所以每一個線程必須同時持有兩個對象鎖,才能繼續執行。一個對象鎖是prev,就是前一個線程所持有的對象鎖。還有一個就是自身對象鎖。主要的思想就是,為了控制執行的順序,必須要先持有prev鎖,也就前一個線程要釋放自身對象鎖,再去申請自身對象鎖,兩者兼備時打印,之后首先調用self.notify()釋放自身對象鎖,喚醒下一個等待線程,再調用prev.wait()釋放prev對象鎖,終止當前線程,等待循環結束后再次被喚醒。運行上述代碼,可以發現三個線程循環打印ABC,共10次。程序運行的主要過程就是A線程最先運行,持有C,A對象鎖,后釋放A,C鎖,喚醒B。線程B等待A鎖,再申請B鎖,后打印B,再釋放B,A鎖,喚醒C,線程C等待B鎖,再申請C鎖,后打印C,再釋放C,B鎖,喚醒A。看起來似乎沒什么問題,但如果你仔細想一下,就會發現有問題,就是初始條件,三個線程按照A,B,C的順序來啟動,按照前面的思考,A喚醒B,B喚醒C,C再喚醒A。但是這種假設依賴于JVM中線程調度、執行的順序。
    ??? wait和sleep區別
    共同點:?

    1. 他們都是在多線程的環境下,都可以在程序的調用處阻塞指定的毫秒數,并返回。
    2. wait()和sleep()都可以通過interrupt()方法 打斷線程的暫停狀態 ,從而使線程立刻拋出InterruptedException。
    ?? 如果線程A希望立即結束線程B,則可以對線程B對應的Thread實例調用interrupt方法。如果此刻線程B正在wait/sleep /join,則線程B會立刻拋出InterruptedException,在catch() {} 中直接return即可安全地結束線程。
    ?? 需要注意的是,InterruptedException是線程自己從內部拋出的,并不是interrupt()方法拋出的。對某一線程調用 interrupt()時,如果該線程正在執行普通的代碼,那么該線程根本就不會拋出InterruptedException。但是,一旦該線程進入到 wait()/sleep()/join()后,就會立刻拋出InterruptedException 。
    不同點:?
    1. Thread類的方法:sleep(),yield()等
    ?? Object的方法:wait()和notify()等
    2. 每個對象都有一個鎖來控制同步訪問。Synchronized關鍵字可以和對象的鎖交互,來實現線程的同步。
    ?? sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他線程可以使用同步控制塊或者方法。?
    3. wait,notify和notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用
    所以sleep()和wait()方法的最大區別是:
        sleep()睡眠時,保持對象鎖,仍然占有該鎖;
        而wait()睡眠時,釋放對象鎖。
      但是wait()和sleep()都可以通過interrupt()方法打斷線程的暫停狀態,從而使線程立刻拋出InterruptedException(但不建議使用該方法)。

    sleep()方法
    sleep()使當前線程進入停滯狀態(阻塞當前線程),讓出CUP的使用、目的是不讓當前線程獨自霸占該進程所獲的CPU資源,以留一定時間給其他線程執行的機會;
       sleep()是Thread類的Static(靜態)的方法;因此他不能改變對象的機鎖,所以當在一個Synchronized塊中調用Sleep()方法是,線程雖然休眠了,但是對象的機鎖并木有被釋放,其他線程無法訪問這個對象(即使睡著也持有對象鎖)。
      在sleep()休眠時間期滿后,該線程不一定會立即執行,這是因為其它線程可能正在運行而且沒有被調度為放棄執行,除非此線程具有更高的優先級。
    wait()方法
    wait()方法是Object類里的方法;當一個線程執行到wait()方法時,它就進入到一個和該對象相關的等待池中,同時失去(釋放)了對象的機鎖(暫時失去機鎖,wait(long timeout)超時時間到后還需要返還對象鎖);其他線程可以訪問;
      wait()使用notify或者notifyAlll或者指定睡眠時間來喚醒當前等待池中的線程。
      wiat()必須放在synchronized block中,否則會在program runtime時扔出”java.lang.IllegalMonitorStateException“異常。

    七、常見線程名詞解釋

    主線程:JVM調用程序main()所產生的線程。 當前線程:這個是容易混淆的概念。一般指通過Thread.currentThread()來獲取的進程。 后臺線程:指為其他線程提供服務的線程,也稱為守護線程。JVM的垃圾回收線程就是一個后臺線程。用戶線程和守護線程的區別在于,是否等待主線程依賴于主線程結束而結束 前臺線程:是指接受后臺線程服務的線程,其實前臺后臺線程是聯系在一起,就像傀儡和幕后操縱者一樣的關系。傀儡是前臺線程、幕后操縱者是后臺線程。由前臺線程創建的線程默認也是前臺線程。可以通過isDaemon()和setDaemon()方法來判斷和設置一個線程是否為后臺線程。 線程類的一些常用方法:?

      sleep(): 強迫一個線程睡眠N毫秒。?
      isAlive(): 判斷一個線程是否存活。?
      join(): 等待線程終止。?
      activeCount(): 程序中活躍的線程數。?
      enumerate(): 枚舉程序中的線程。?
    ??? currentThread(): 得到當前線程。?
      isDaemon(): 一個線程是否為守護線程。?
      setDaemon(): 設置一個線程為守護線程。(用戶線程和守護線程的區別在于,是否等待主線程依賴于主線程結束而結束)?
      setName(): 為線程設置一個名稱。?
      wait(): 強迫一個線程等待。?
      notify(): 通知一個線程繼續運行。?
      setPriority(): 設置一個線程的優先級。

    八、線程同步

    1、synchronized關鍵字的作用域有二種:?
    1)是某個對象實例內,synchronized aMethod(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;?
    2)是某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。?

    2、除了方法前用synchronized關鍵字,synchronized關鍵字還可以用于方法中的某個區塊中,表示只對這個區塊的資源實行互斥訪問。用法是: synchronized(this){/*區塊*/},它的作用域是當前對象;?

    3、synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中并不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;?

    Java對多線程的支持與同步機制深受大家的喜愛,似乎看起來使用了synchronized關鍵字就可以輕松地解決多線程共享數據同步問題。到底如何?――還得對synchronized關鍵字的作用進行深入了解才可定論。

    總的說來,synchronized關鍵字可以作為函數的修飾符,也可作為函數內的語句,也就是平時說的同步方法和同步語句塊。如果再細的分類,synchronized可作用于instance變量、object reference(對象引用)、static函數和class literals(類名稱字面常量)身上。

    在進一步闡述之前,我們需要明確幾點:

    A.無論synchronized關鍵字加在方法上還是對象上,它取得的鎖都是對象,而不是把一段代碼或函數當作鎖――而且同步方法很可能還會被其他線程的對象訪問。

    B.每個對象只有一個鎖(lock)與之相關聯。

    C.實現同步是要很大的系統開銷作為代價的,甚至可能造成死鎖,所以盡量避免無謂的同步控制。

    接著來討論synchronized用到不同地方對代碼產生的影響:

    假設P1、P2是同一個類的不同對象,這個類中定義了以下幾種情況的同步塊或同步方法,P1、P2就都可以調用它們。

    1.? 把synchronized當作函數修飾符時,示例代碼如下:

    [java]view plaincopy
  • Public?synchronized?void?methodAAA()??
  • {??
  • //….??
  • }??
  • 這也就是同步方法,那這時synchronized鎖定的是哪個對象呢?它鎖定的是調用這個同步方法對象。也就是說,當一個對象P1在不同的線程中執行這個同步方法時,它們之間會形成互斥,達到同步的效果。但是這個對象所屬的Class所產生的另一對象P2卻可以任意調用這個被加了synchronized關鍵字的方法。

    上邊的示例代碼等同于如下代碼:

    [java]view plaincopy
  • public?void?methodAAA()??
  • {??
  • synchronized?(this)??????//??(1)??
  • {??
  • ???????//…..??
  • }??
  • }??
  • ?(1)處的this指的是什么呢?它指的就是調用這個方法的對象,如P1。可見同步方法實質是將synchronized作用于object reference。――那個拿到了P1對象鎖的線程,才可以調用P1的同步方法,而對P2而言,P1這個鎖與它毫不相干,程序也可能在這種情形下擺脫同步機制的控制,造成數據混亂:(

    2.同步塊,示例代碼如下:

    [java]view plaincopy
  • ????????????public?void?method3(SomeObject?so)??
  • ??????????????{??
  • ?????????????????????synchronized(so)??
  • {??
  • ???????//…..??
  • }??
  • }??
  • 這時,鎖就是so這個對象,誰拿到這個鎖誰就可以運行它所控制的那段代碼。當有一個明確的對象作為鎖時,就可以這樣寫程序,但當沒有明確的對象作為鎖,只是想讓一段代碼同步時,可以創建一個特殊的instance變量(它得是一個對象)來充當鎖:

    [java]view plaincopy
  • class?Foo?implements?Runnable??
  • {??
  • ???????private?byte[]?lock?=?new?byte[0];??//?特殊的instance變量??
  • ????Public?void?methodA()??
  • {??
  • ???????synchronized(lock)?{?//…?}??
  • }??
  • //…..??
  • }??
  • 注:零長度的byte數組對象創建起來將比任何對象都經濟――查看編譯后的字節碼:生成零長度的byte[]對象只需3條操作碼,而Object lock = new Object()則需要7行操作碼。

    3.將synchronized作用于static 函數,示例代碼如下:

    [java]view plaincopy
  • Class?Foo??
  • {??
  • public?synchronized?static?void?methodAAA()???//?同步的static?函數??
  • {??
  • //….??
  • }??
  • public?void?methodBBB()??
  • {??
  • ???????synchronized(Foo.class)???//??class?literal(類名稱字面常量)??
  • }??
  • ???????}??
  • ?? 代碼中的methodBBB()方法是把class literal作為鎖的情況,它和同步的static函數產生的效果是一樣的,取得的鎖很特別,是當前調用這個方法的對象所屬的類(Class,而不再是由這個Class產生的某個具體對象了)。

    記得在《Effective Java》一書中看到過將 Foo.class和 P1.getClass()用于作同步鎖還不一樣,不能用P1.getClass()來達到鎖這個Class的目的。P1指的是由Foo類產生的對象。

    可以推斷:如果一個類中定義了一個synchronized的static函數A,也定義了一個synchronized 的instance函數B,那么這個類的同一對象Obj在多線程中分別訪問A和B兩個方法時,不會構成同步,因為它們的鎖都不一樣。A方法的鎖是Obj這個對象,而B的鎖是Obj所屬的那個Class。

    總結一下:

    1、線程同步的目的是為了保護多個線程反問一個資源時對資源的破壞。
    2、線程同步方法是通過鎖來實現,每個對象都有切僅有一個鎖,這個鎖與一個特定的對象關聯,線程一旦獲取了對象鎖,其他訪問該對象的線程就無法再訪問該對象的其他非同步方法
    3、對于靜態同步方法,鎖是針對這個類的,鎖對象是該類的Class對象。靜態和非靜態方法的鎖互不干預。一個線程獲得鎖,當在一個同步方法中訪問另外對象上的同步方法時,會獲取這兩個對象鎖。
    4、對于同步,要時刻清醒在哪個對象上同步,這是關鍵。
    5、編寫線程安全的類,需要時刻注意對多個線程競爭訪問資源的邏輯和安全做出正確的判斷,對“原子”操作做出分析,并保證原子操作期間別的線程無法訪問競爭資源。
    6、當多個線程等待一個對象鎖時,沒有獲取到鎖的線程將發生阻塞。
    7、死鎖是線程間相互等待鎖鎖造成的,在實際中發生的概率非常的小。真讓你寫個死鎖程序,不一定好使,呵呵。但是,一旦程序發生死鎖,程序將死掉。

    九、線程數據傳遞

    在傳統的同步開發模式下,當我們調用一個函數時,通過這個函數的參數將數據傳入,并通過這個函數的返回值來返回最終的計算結果。但在多線程的異步開發模式下,數據的傳遞和返回和同步開發模式有很大的區別。由于線程的運行和結束是不可預料的,因此,在傳遞和返回數據時就無法象函數一樣通過函數參數和return語句來返回數據。

    9.1、通過構造方法傳遞數據?
    在創建線程時,必須要建立一個Thread類的或其子類的實例。因此,我們不難想到在調用start方法之前通過線程類的構造方法將數據傳入線程。并將傳入的數據使用類變量保存起來,以便線程使用(其實就是在run方法中使用)。下面的代碼演示了如何通過構造方法來傳遞數據:?

    [java]view plaincopy
  • ???
  • package?mythread;???
  • public?class?MyThread1?extends?Thread???
  • {???
  • private?String?name;???
  • public?MyThread1(String?name)???
  • {???
  • this.name?=?name;???
  • }???
  • public?void?run()???
  • {???
  • System.out.println("hello?"?+?name);???
  • }???
  • public?static?void?main(String[]?args)???
  • {???
  • Thread?thread?=?new?MyThread1("world");???
  • thread.start();???
  • }???
  • }???
  • 由于這種方法是在創建線程對象的同時傳遞數據的,因此,在線程運行之前這些數據就就已經到位了,這樣就不會造成數據在線程運行后才傳入的現象。如果要傳遞更復雜的數據,可以使用集合、類等數據結構。使用構造方法來傳遞數據雖然比較安全,但如果要傳遞的數據比較多時,就會造成很多不便。由于Java沒有默認參數,要想實現類似默認參數的效果,就得使用重載,這樣不但使構造方法本身過于復雜,又會使構造方法在數量上大增。因此,要想避免這種情況,就得通過類方法或類變量來傳遞數據。?

    9.2、通過變量和方法傳遞數據?
    向對象中傳入數據一般有兩次機會,第一次機會是在建立對象時通過構造方法將數據傳入,另外一次機會就是在類中定義一系列的public的方法或變量(也可稱之為字段)。然后在建立完對象后,通過對象實例逐個賦值。下面的代碼是對MyThread1類的改版,使用了一個setName方法來設置 name變量:?

    [java]view plaincopy
  • ???
  • package?mythread;???
  • public?class?MyThread2?implements?Runnable???
  • {???
  • private?String?name;???
  • public?void?setName(String?name)???
  • {???
  • this.name?=?name;???
  • }???
  • public?void?run()???
  • {???
  • System.out.println("hello?"?+?name);???
  • }???
  • public?static?void?main(String[]?args)???
  • {???
  • MyThread2?myThread?=?new?MyThread2();???
  • myThread.setName("world");???
  • Thread?thread?=?new?Thread(myThread);???
  • thread.start();???
  • }???
  • }???
  • 9.3、通過回調函數傳遞數據?

    上面討論的兩種向線程中傳遞數據的方法是最常用的。但這兩種方法都是main方法中主動將數據傳入線程類的。這對于線程來說,是被動接收這些數據的。然而,在有些應用中需要在線程運行的過程中動態地獲取數據,如在下面代碼的run方法中產生了3個隨機數,然后通過Work類的process方法求這三個隨機數的和,并通過Data類的value將結果返回。從這個例子可以看出,在返回value之前,必須要得到三個隨機數。也就是說,這個 value是無法事先就傳入線程類的。?

    [java]view plaincopy
  • ???
  • package?mythread;???
  • class?Data???
  • {???
  • public?int?value?=?0;???
  • }???
  • class?Work???
  • {???
  • public?void?process(Data?data,?Integer?numbers)???
  • {???
  • for?(int?n?:?numbers)???
  • {???
  • data.value?+=?n;???
  • }???
  • }???
  • }???
  • public?class?MyThread3?extends?Thread???
  • {???
  • private?Work?work;???
  • public?MyThread3(Work?work)???
  • {???
  • this.work?=?work;???
  • }???
  • public?void?run()???
  • {???
  • java.util.Random?random?=?new?java.util.Random();???
  • Data?data?=?new?Data();???
  • int?n1?=?random.nextInt(1000);???
  • int?n2?=?random.nextInt(2000);???
  • int?n3?=?random.nextInt(3000);???
  • work.process(data,?n1,?n2,?n3);?//?使用回調函數???
  • System.out.println(String.valueOf(n1)?+?"+"?+?String.valueOf(n2)?+?"+"???
  • +?String.valueOf(n3)?+?"="?+?data.value);???
  • }???
  • public?static?void?main(String[]?args)???
  • {???
  • Thread?thread?=?new?MyThread3(new?Work());???
  • thread.start();???
  • }???
  • }???
  • ? 好了,Java多線程的基礎知識就講到這里了,有興趣研究多線程的推薦直接看java的源碼,你將會得到很大的提升!

    轉載出處http://blog.csdn.net/evankaka

    總結

    以上是生活随笔為你收集整理的Java多线程学习的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    天天干天天在线 | 激情视频综合网 | 国产视频九色蝌蚪 | 国产精品久久艹 | 精品国产1区二区 | 久久一区二区三区超碰国产精品 | 色干干 | 97在线影院 | 日日操夜夜操狠狠操 | 亚洲精品中文字幕在线 | 久久久国产精品视频 | 天天操狠狠操网站 | 99国产精品久久久久久久久久 | 18久久久久 | 国产福利一区二区三区视频 | 国产原厂视频在线观看 | 天天操夜夜逼 | 激情喷水| 国产资源中文字幕 | 香蕉国产91 | 欧美日韩综合在线观看 | 中文字幕在线中文 | 午夜久久网 | 99人成在线观看视频 | 日日干日日操 | 午夜在线免费视频 | 射久久 | 色综合网在线 | 天天综合成人网 | 国产成人精品不卡 | 久久久久夜色 | 久久伦理电影 | 韩日精品在线观看 | 伊人射 | 国产涩涩网站 | 亚洲国内精品视频 | 国产黄色成人av | 97国产大学生情侣酒店的特点 | 欧美一级专区免费大片 | 国产亚洲综合精品 | 最新国产一区二区三区 | 激情五月伊人 | 91激情小视频 | 500部大龄熟乱视频使用方法 | 99人成在线观看视频 | 国产看片网站 | 成人在线视频你懂的 | 亚洲一级电影视频 | 69国产盗摄一区二区三区五区 | 欧美一级在线看 | 亚洲成av人影院 | 免费视频一区二区 | 深爱激情婷婷网 | 午夜少妇一区二区三区 | 成人午夜精品久久久久久久3d | 欧美精品久久久久 | 日韩免费在线视频 | 欧美性大胆 | 69精品人人人人 | 国产 日韩 在线 亚洲 字幕 中文 | 91亚色在线观看 | av日韩精品 | 成人黄色在线视频 | 天天碰天天操 | 成人在线一区二区 | 久久亚洲综合国产精品99麻豆的功能介绍 | 69视频国产 | www.色五月.com | 久久黄色免费视频 | 国产午夜激情视频 | 69成人在线| 欧美日韩二区在线 | 4p变态网欧美系列 | 91系列在线观看 | 国产一级精品绿帽视频 | 人人爽人人片 | 九九热免费观看 | 美女视频黄免费网站 | 国产美女免费观看 | 又湿又紧又大又爽a视频国产 | 五月天六月丁香 | 欧美福利片在线观看 | 国产一卡久久电影永久 | 亚州国产视频 | 久草在线视频看看 | 精品影院一区二区久久久 | 中文字幕人成不卡一区 | 亚洲视频资源在线 | 久久av免费 | 91精品播放| 有码中文字幕在线观看 | 国产美女久久久 | 日韩精品最新在线观看 | 天天天干天天天操 | 久久久久久蜜桃一区二区 | 欧美精品在线观看一区 | 国内精品免费 | 欧美在线久久 | 久久精品99久久久久久2456 | 久久成人精品视频 | 2024国产精品视频 | 欧美日韩高清一区 | 国产一区二区不卡视频 | 国产理论一区二区三区 | 在线日韩中文 | 久草热久草视频 | 一区二区精品在线 | 日韩av资源在线观看 | www91在线观看 | 91九色国产在线 | 91精品啪 | 亚洲情影院 | www最近高清中文国语在线观看 | 天天干天天操 | 国产精品一区在线播放 | 99精品在线视频播放 | 国产一区二区三区网站 | 国产一级视频 | 在线免费观看一区二区三区 | 91麻豆免费视频 | 日日夜夜狠狠 | 欧美a级片免费看 | 亚洲综合激情网 | 欧美aa一级片 | 精品不卡视频 | 福利精品在线 | 亚洲国产成人精品电影在线观看 | 天堂av最新网址 | 成在线播放 | 久久狠狠婷婷 | 国产91成人 | 天天天天天干 | 欧洲精品久久久久毛片完整版 | 色老板在线 | 激情婷婷亚洲 | 麻豆精品传媒视频 | 丁香九月婷婷综合 | 91免费国产在线观看 | 国产一区免费观看 | 精品国产一二区 | zzijzzij亚洲日本少妇熟睡 | 久久久久久久久久久综合 | 亚洲精品在线观看av | 天天插日日射 | 日韩在线观看第一页 | 香蕉久久久久久av成人 | 中文字幕资源在线观看 | 99视频偷窥在线精品国自产拍 | 99国产精品视频免费观看一公开 | 福利视频一区二区 | 国产成人一区二区三区在线观看 | 丁香五月亚洲综合在线 | 一区二区日韩av | 亚洲伦理一区二区 | 黄色片免费看 | 久草爱视频 | 亚洲黄色av一区 | 国产免费大片 | 亚洲一级电影视频 | 久久超碰在线 | 中文久草| 97精品国产97久久久久久春色 | 中文 一区二区 | 黄色官网在线观看 | 怡红院av久久久久久久 | 亚洲春色奇米影视 | 国产日产亚洲精华av | 97精品国产一二三产区 | 一区二区视频网站 | 亚洲视频在线看 | 国产日韩欧美在线 | 久久久久久久影视 | 久久公开免费视频 | 69久久久久久久 | 黄色app网站在线观看 | 久久视频这里只有精品 | 草久热| 在线观看亚洲国产精品 | 欧美日韩一级久久久久久免费看 | 久久在线 | 亚洲va韩国va欧美va精四季 | 美女在线免费视频 | 免费看久久 | 国产精品久久久久久久久久免费看 | 激情网色| 国产精品一区二区在线播放 | 国产破处在线视频 | 97在线观 | 久久无码av一区二区三区电影网 | 99视频久 | 色欧美综合 | 久久久久观看 | 最新中文字幕 | 欧美日韩色婷婷 | 超碰公开在线 | 国产精品成人av电影 | 色综合久久综合 | 久久国产精品免费视频 | 久久久免费网站 | a级国产乱理伦片在线观看 亚洲3级 | 日韩电影在线观看一区二区 | 精品亚洲va在线va天堂资源站 | 狠狠的日日 | a黄色影院 | 久久天天综合网 | 久久国产精品偷 | 伊人小视频 | 91日韩精品视频 | 国产一线二线三线在线观看 | 91免费高清视频 | 麻豆视屏 | 六月婷婷网 | 九九九九九国产 | 一区视频在线 | 91最新在线视频 | 制服丝袜欧美 | 国产精品99久久久久久宅男 | 又爽又黄又无遮挡网站动态图 | 国产精品网在线观看 | 国产看片免费 | av电影亚洲 | 亚洲欧美激情插 | 人人干人人上 | 色综合久久久久久久 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 欧美久久九九 | 日日躁夜夜躁xxxxaaaa | av电影免费在线播放 | 一本一道波多野毛片中文在线 | 久久免费看av | 日韩精品久久久久久中文字幕8 | 999久久久欧美日韩黑人 | 蜜臀久久99精品久久久酒店新书 | 狠狠色伊人亚洲综合成人 | 日本乱视频 | 亚洲伊人网在线观看 | www.五月天婷婷| 五月婷婷黄色网 | 99久久99久国产黄毛片 | 青青河边草手机免费 | 天天爽夜夜爽人人爽一区二区 | 东方av免费在线观看 | 香蕉久久久久 | 国产中文字幕视频在线观看 | 亚洲精品美女在线观看 | 久久免费视频2 | 99精品久久精品一区二区 | 99精品免费久久久久久久久日本 | 日韩在线免费高清视频 | 天天综合色网 | 999成人网 | 国产最新视频在线 | 久草精品视频 | 综合激情婷婷 | 天天操夜夜逼 | 亚洲激情网站免费观看 | www.国产在线视频 | 久久国产精品免费一区二区三区 | 亚洲天堂网视频在线观看 | 奇米影音四色 | 中文字幕的| 91av小视频| 中文av不卡| 成人一区影院 | 五月婷婷中文网 | 日本在线观看一区二区 | 中文字幕网址 | 亚洲综合在线一区二区三区 | 亚洲综合婷婷 | 国产中文字幕一区二区三区 | 免费特级黄毛片 | 丁香激情五月 | 97成人免费| 福利一区在线视频 | 91黄色影视 | 成人免费在线观看av | 婷婷色社区 | www欧美日韩 | 欧美一级在线观看视频 | 天天操夜夜看 | 啪啪精品 | 成 人 黄 色 免费播放 | 日日久视频 | 婷婷六月丁| 天天综合色天天综合 | 亚洲日韩精品欧美一区二区 | 欧美成人精品三级在线观看播放 | 少妇搡bbbb搡bbb搡忠贞 | 一区二区三区免费在线观看视频 | free,性欧美 九九交易行官网 | 国产精品99久久久久久人免费 | 99久久精品国产一区二区成人 | 在线观看www. | av字幕在线 | 在线成人免费电影 | 在线观看日韩精品 | 色妞色视频一区二区三区四区 | 中文字幕在线视频国产 | 五月天婷婷免费视频 | 黄色软件在线观看免费 | 黄色毛片在线 | 天天玩天天操天天射 | 国产免费一区二区三区网站免费 | 日本精品在线视频 | 日韩欧美高清一区二区三区 | 天天操天天操天天操天天操 | 丁香色天天 | 午夜久操 | а天堂中文最新一区二区三区 | 亚洲精选视频在线 | 永久免费的啪啪网站免费观看浪潮 | 欧美精品乱码久久久久久按摩 | 99久久影院 | 人人超碰人人 | 在线电影 你懂得 | 国产成人黄色在线 | 亚洲国产精品电影 | 最近日本韩国中文字幕 | 欧美成人精品欧美一级乱 | 91av在线视频播放 | 人人揉人人揉人人揉人人揉97 | 成人久久免费 | 久久人人插 | 在线观看91精品国产网站 | 国产麻豆精品传媒av国产下载 | 亚洲欧美日韩国产一区二区三区 | 日韩在线免费视频 | 国产婷婷精品av在线 | 在线黄av | 国产 在线 日韩 | 一区二区三区动漫 | 久久av黄色 | 激情综合久久 | 一级片黄色片网站 | 免费看v片 | 久久国产精品小视频 | 99久久99久久精品国产片果冰 | 日韩中文字幕网站 | 日韩精选在线 | 天天玩天天干 | 激情五月色播五月 | 久久人人爽人人爽人人 | 日本性生活免费看 | av在线网站大全 | 日韩久久久久久久久 | 99热免费在线 | 欧美最猛性xxxxx免费 | 久久美女高清视频 | 日本免费久久高清视频 | 中文字幕在线高清 | 最近中文字幕第一页 | 国内精品一区二区 | 久久无码精品一区二区三区 | 又黄又爽又湿又无遮挡的在线视频 | 国产精品欧美一区二区三区不卡 | 国内精品久久久久影院一蜜桃 | 久久精品影视 | 人人澡澡人人 | 99性视频 | 精品国产一区二区三区四区在线观看 | 久久久精品网 | www视频在线免费观看 | 日韩免费高清在线 | 欧美精品免费在线 | 九九热在线免费观看 | 91在线看视频免费 | 在线一区电影 | 免费看一级 | 日韩欧美电影 | 国产黄色一级大片 | 婷婷社区五月天 | 在线视频国产区 | 99精品在线视频观看 | 精品久久久久亚洲 | 国产亚洲在线观看 | 91亚洲精品久久久久图片蜜桃 | 成年人在线观看视频免费 | 精品国产成人在线影院 | 天天做综合网 | 国产成人精品在线观看 | 波多野结衣资源 | av网站手机在线观看 | 欧洲精品视频一区 | 四虎成人精品永久免费av九九 | 色噜噜日韩精品一区二区三区视频 | 免费看黄在线看 | 揉bbb玩bbb少妇bbb | 99精品久久久久久久久久综合 | 青青看片| 在线色亚洲 | 国产精品你懂的在线观看 | 91看片淫黄大片在线播放 | 日日爱夜夜爱 | 天天操天天摸天天爽 | 国产精品视频免费 | www.国产精品 | 久草精品在线观看 | 狠狠躁夜夜a产精品视频 | 青青河边草观看完整版高清 | 久久久久网站 | 天天想夜夜操 | 国产精品久久久久一区二区国产 | 色999在线| 中文字幕视频一区二区 | 中文国产在线观看 | 鲁一鲁影院 | 国产精品国产亚洲精品看不卡 | 天天草天天干天天 | 色婷婷福利视频 | 国产中文字幕视频在线观看 | 97超视频| 91欧美在线 | 成人免费在线看片 | 黄色的网站在线 | 国产精品18久久久久久久久 | 成人免费在线视频观看 | 日韩电影一区二区三区在线观看 | 在线视频a | 一区二区欧美日韩 | 中文电影网 | 国产高清视频色在线www | 亚洲不卡av一区二区三区 | 天天天天色综合 | 国产69精品久久久久久久久久 | 久久9999久久 | 玖玖视频网| 成人在线网站观看 | 国内外激情视频 | 草久在线观看视频 | 不卡的av在线播放 | 欧美孕交vivoestv另类 | 亚洲精品永久免费视频 | 91网站在线视频 | 国产伦理精品一区二区 | 成人精品视频久久久久 | 久久久久免费精品国产小说色大师 | 欧美另类调教 | 99国产精品免费网站 | 奇米影视8888在线观看大全免费 | 亚洲伊人婷婷 | 人人射人人射 | 国产成人a v电影 | 久草成人在线 | 99视频+国产日韩欧美 | 香蕉视频久久久 | 久久久久日本精品一区二区三区 | 欧美日韩在线精品 | 国产3p视频 | 国产一区二区久久久 | 九九久久影视 | 国产成人精品在线播放 | 五月天激情婷婷 | 久久在线免费 | 免费在线观看av网站 | 欧美激情片在线观看 | 国产视频一级 | 国产91在线观 | 久久久久国产一区二区三区 | 欧美亚洲国产精品久久高清浪潮 | 在线一级片 | 精品国产一区二区三区蜜臀 | 中文字幕高清有码 | 精品久久99 | 婷婷5月色 | 一区二区 不卡 | 久久久久久久毛片 | av免费网站观看 | 色婷婷国产在线 | 国产视频一区二区三区在线 | 亚洲激情在线播放 | 天天综合天天做天天综合 | www黄com| 亚洲五月婷婷 | 五月婷婷综 | 免费无遮挡动漫网站 | 99自拍视频在线观看 | 伊人国产在线播放 | 成人三级av | 午夜视频在线观看网站 | 久草视频在线观 | 99热这里有 | 亚洲.www | av在线收看 | 欧美日本一区 | 久久精品系列 | 日韩动态视频 | 色综合久久综合 | 亚洲精品在线网站 | 黄色电影网站在线观看 | 日韩黄色在线 | 九九免费在线观看视频 | av免费网页 | 国产成人精品在线 | 天天摸夜夜操 | 亚洲黄色激情小说 | 免费看片成年人 | 亚洲自拍偷拍色图 | 国产精品久久久久久久久久久久午夜片 | 欧美日韩精品网站 | 少妇视频在线播放 | 国偷自产视频一区二区久 | 美女网站在线 | 色诱亚洲精品久久久久久 | 国产精品久久久久久久久费观看 | 国产破处在线视频 | 香蕉国产91 | 亚洲一区网站 | 日韩在线播放视频 | 永久免费在线 | 国产精品一区二区62 | 国产精品淫片 | 国产一级电影网 | 色干综合 | 91豆麻精品91久久久久久 | 激情五月婷婷综合 | 久草在线免费资源 | 精品国产一区二区三区久久久蜜臀 | 丰满少妇久久久 | 91亚洲精品久久久蜜桃网站 | 三级小视频在线观看 | 国产做a爱一级久久 | 精油按摩av| www黄色软件 | 精品一区精品二区高清 | 免费中文字幕 | 日韩 在线| 天天躁日日躁狠狠躁 | 黄色一级免费电影 | 最新久久久 | 亚洲午夜不卡 | 日本天天操 | 草久在线播放 | 久久九九影视 | 亚洲精品免费在线 | 97视频播放 | 99国产视频 | 亚洲国产激情 | 亚洲激情中文 | 日韩欧美国产精品 | 国产精品资源网 | 麻豆成人精品视频 | 成人黄色大片 | 精品乱码一区二区三四区 | 日韩av综合网站 | 欧美视频日韩 | 久久九九影视 | 99久久综合精品五月天 | 国产色视频网站 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 国产精品99久久久久久大便 | 国产精品视频专区 | 日韩在线色 | 成人小视频在线播放 | av福利在线免费观看 | 日韩电影一区二区在线 | 免费视频一区二区 | 在线免费观看的av网站 | 日日爱网址 | 欧美久久久久久久 | 正在播放 国产精品 | 99re国产视频 | 伊人黄色网 | 日韩乱理| 久久综合色播五月 | 国产在线观看免 | 毛片3 | 亚洲综合在线五月 | 国产va饥渴难耐女保洁员在线观看 | 国产精品一区二区三区在线免费观看 | 超碰av免费| 久久久久久久久亚洲精品 | 日本在线观看黄色 | 插久久 | 免费在线色视频 | 97手机电影网 | 欧美国产日韩一区二区三区 | 日韩午夜网站 | 在线看成人av | 久久精品综合一区 | 99视频免费在线观看 | 欧美爽爽爽| 麻豆网站免费观看 | 久久亚洲欧美日韩精品专区 | 日日干天天 | 国产午夜免费视频 | 中文字幕二区在线观看 | 国产视频精品在线 | 精品国产欧美一区二区 | 久久久精品一区二区三区 | 中文字幕丰满人伦在线 | 奇米影视8888 | 日本丶国产丶欧美色综合 | 久久久久久黄 | 97超碰精品| 久久精品99国产精品亚洲最刺激 | 国产日韩精品在线观看 | 黄色www| 日韩av在线资源 | 国产看片网站 | 在线观看的a站 | 国产在线97 | www.天天色.com| 久久久午夜精品理论片中文字幕 | 色婷婷啪啪免费在线电影观看 | 尤物一区二区三区 | 中文字幕久久久精品 | 欧美在线视频一区二区三区 | 国产亚洲成av片在线观看 | 99r在线精品| 五月激情亚洲 | 免费网站在线观看成人 | 欧美日韩国产亚洲乱码字幕 | 人人插人人爱 | 国产亚洲精品福利 | 久久综合久久久 | 99视频在线观看一区三区 | 伊人婷婷色| 午夜精品一二三区 | 91成人免费在线视频 | 三三级黄色片之日韩 | 成人高清在线 | 大胆欧美gogo免费视频一二区 | 国产99亚洲 | 久久香蕉一区 | 久久久久久麻豆 | 成人看片 | 97色在线视频 | 日韩精品一区二 | 丁香视频全集免费观看 | 亚洲免费观看视频 | 免费观看久久 | 成人在线视频观看 | 亚洲免费在线观看视频 | 国产超碰在线 | 极品久久久久久久 | 久久超级碰 | 日韩国产精品毛片 | 在线视频观看你懂的 | 国产精品日韩 | 丁香激情综合 | 狠狠躁日日躁夜夜躁av | 欧美久久久久久久久久久 | 激情久久网 | 天天射天天射 | 精品久久久久久亚洲综合网站 | 精品亚洲免费 | 成人三级网址 | 香蕉久草在线 | 久久亚洲免费视频 | 国产夫妻性生活自拍 | 国产视频91在线 | 在线观看国产区 | 国产色网站 | 天天躁日日躁狠狠躁av中文 | 狠狠干网站 | 91精选 | 亚洲综合欧美精品电影 | 婷婷婷国产在线视频 | 97偷拍在线视频 | 日韩成人精品 | 香蕉免费在线 | 黄视频色网站 | 国产操在线 | 99爱在线 | 日韩手机在线 | 国产91精品一区二区 | 五月天激情电影 | 在线日韩中文 | 久久综合狠狠综合久久狠狠色综合 | 91 中文字幕 | 成人在线视频一区 | 国产精品久久久久一区 | 日本在线观看中文字幕 | 天天做天天爱夜夜爽 | 91av视频导航| 亚洲激情视频在线 | 亚洲伊人av | 一区视频在线 | 国产一二三在线视频 | 精品自拍sae8—视频 | 欧美 日韩 成人 | 免费av在线播放 | 亚洲小视频在线 | 97人人模人人爽人人喊网 | 69精品在线观看 | 亚洲综合欧美日韩狠狠色 | 欧美综合干 | 四虎影视成人永久免费观看视频 | 色婷久久| 国产精品毛片一区二区三区 | 91最新在线观看 | 久久久久免费精品国产小说色大师 | 欧美精品久久久久 | 成年人在线播放视频 | 免费亚洲片 | 69精品在线 | 国产精品国产亚洲精品看不卡 | av黄网站 | 亚洲国产精品第一区二区 | 久久伦理 | 欧美日韩一区二区三区免费视频 | www.亚洲| 欧美日韩中文字幕在线视频 | 国产大片黄色 | 超碰在线观看av.com | 99在线观看 | 黄色成品视频 | 午夜精品福利一区二区三区蜜桃 | 99超碰在线观看 | 免费精品视频在线观看 | 亚洲黄a | 天天操夜夜操夜夜操 | 欧美日韩久久久 | 丁香av | 欧美日韩中文在线观看 | 91在线你懂的 | 天天婷婷 | 99爱视频在线观看 | 天堂av免费观看 | 日韩欧美不卡 | 日韩欧美极品 | 日韩视频1区| 一区二区中文字幕在线 | 免费看片在线观看 | 成人免费观看网址 | 97超碰成人在线 | 久久精品区| 最新国产在线 | 91精品对白一区国产伦 | 特黄特色特刺激视频免费播放 | 91精品黄色| 国产99区 | 日韩理论在线观看 | 97超碰在线视| av三级在线播放 | 国产免费激情久久 | 久久精品一| 91亚色在线观看 | 青青河边草观看完整版高清 | 99婷婷狠狠成为人免费视频 | 国产亚洲精品久久久久久网站 | 欧洲激情综合 | 开心激情久久 | 中中文字幕av| 豆豆色资源网xfplay | 日韩精品中文字幕在线 | 欧美九九视频 | 免费黄a大片 | 日本精品久久久久久 | 日韩在线视频线视频免费网站 | 欧美一级片在线播放 | 日韩视频一 | 天天操夜 | 亚洲人人爱 | 91视频高清 | 免费看毛片网站 | 欧美aa级| 天天摸天天操天天舔 | 99精品欧美一区二区三区 | 国产精品爽爽久久久久久蜜臀 | 亚洲aⅴ免费在线观看 | 成人av在线一区二区 | 91精品国产一区二区在线观看 | 欧美性黄网官网 | 久久精品亚洲精品国产欧美 | 超碰人人在 | 99久久99久久综合 | 欧美地下肉体性派对 | 欧美精品网站 | av电影中文 | 中文字幕 成人 | 婷婷精品国产一区二区三区日韩 | 久久久久亚洲精品国产 | japanesexxxhd奶水 91在线精品一区二区 | 美女免费网站 | 香蕉精品在线观看 | 久久久久国| 99久久精品免费看国产免费软件 | 国产二级视频 | 精品在线观 | 伊人婷婷网 | 色综合夜色一区 | 黄色片免费在线 | 激情五月婷婷网 | 综合天天| 99在线热播| 四虎精品成人免费网站 | 久久99精品国产麻豆宅宅 | 鲁一鲁影院 | 天天操综 | 亚洲激情电影在线 | 激情五月综合网 | 99色免费视频 | 国产黄色在线看 | 黄色1级毛片 | 草久久久久久久 | 麻豆精品视频在线 | 狠狠操夜夜操 | 久久精品国产亚洲 | 精品国产一区二区三区四区vr | 网站免费黄色 | 色.com| 午夜av片 | 97偷拍在线视频 | 91污污 | 日韩视频免费播放 | 成人午夜毛片 | 色爱区综合激月婷婷 | 中文字幕在线播放一区二区 | 亚洲在线精品视频 | 精品美女久久久久久免费 | 免费观看mv大片高清 | 中文字幕第一页在线视频 | 国产在线精品一区二区 | 国内一级片在线观看 | 欧美日韩网站 | 看毛片网站 | 色婷婷久久一区二区 | 久久综合色影院 | 国产成人免费在线 | 九色激情网 | 中文字幕中文字幕在线中文字幕三区 | 青青河边草免费视频 | 丁香婷婷电影 | 久久久久久久久久久久久久电影 | 高潮久久久久久久久 | 国产又粗又猛又色 | 99久久精品久久久久久动态片 | 国产精品久久久久久婷婷天堂 | 五月情婷婷 | 九色91在线视频 | 婷婷丁香激情五月 | 深爱激情五月婷婷 | 欧美成人h版电影 | 91精品久久久久久 | 亚洲欧美激情精品一区二区 | 五月开心网 | 天天干天天插伊人网 | 国产精品久久久久免费观看 | 日韩av电影中文字幕在线观看 | 亚洲精品国产精品国自产 | 超碰97.com| 国产成在线观看免费视频 | 国产美女视频免费观看的网站 | 91视频首页 | 国产成人精品一区二区在线 | 99久久久| 精品久久亚洲 | 中文字幕av网站 | 青青啪 | 99久久精品免费一区 | 午夜91在线 | 高清视频一区 | 五月天久久 | 日韩视频免费观看高清 | 欧美精品国产综合久久 | 国产无套视频 | 日韩欧美一区二区三区视频 | 精品一区二区三区久久久 | 国产伦精品一区二区三区免费 | 最新日韩视频 | 91激情视频在线观看 | 午夜视频播放 | 99免费在线播放99久久免费 | 日韩三级视频在线观看 | 国产精品99久久久久久宅男 | 国产午夜精品一区二区三区 | 伊人伊成久久人综合网站 | 美女免费黄视频网站 | 日韩丝袜| 久久天天躁狠狠躁夜夜不卡公司 | 午夜视频一区二区三区 | 久久精品视频4 | av永久网址 | 男女免费视频观看 | 天天想夜夜操 | 黄色三级免费片 | 国产成人在线综合 | 国产精品视频在线看 | 西西www4444大胆在线 | 91精品国产成人 | 九九免费在线观看 | 久久久亚洲成人 | 国产香蕉视频在线播放 | 免费a级大片 | 青春草视频 | 久久97精品| 国产日韩欧美在线观看视频 | 91精品导航 | 欧美一级在线观看视频 | 少妇bbw揉bbb欧美 | 日本精品一区二区三区在线播放视频 | 在线色亚洲 | 国产成人精品国内自产拍免费看 | 天天干天天操人体 | 久久精品国产亚洲aⅴ | 日韩久久精品一区二区 | 久久婷亚洲五月一区天天躁 | 18国产精品白浆在线观看免费 | 最近日韩免费视频 | 久久久精品电影 | 特级黄色片免费看 | 四虎永久免费 | 亚洲一二三区精品 | wwxxxx日本| 中文字幕一区二区三区四区 | 国产99久久久国产精品免费二区 | 91福利在线导航 | 精品久久久久久久久中文字幕 | 一级黄色大片 | 国产精品久久久久久一区二区 | 色姑娘综合 | 久久综合欧美 | 337p西西人体大胆瓣开下部 | 国产精品99久久久久久久久 | 国产福利在线免费 | 国产精品99免费看 | 狠狠色丁香婷婷 | 欧美一级视频免费 | 免费日韩视 | 久久电影中文字幕视频 | 国产亚洲精品日韩在线tv黄 | 在线观看第一页 | 一区二区三区韩国免费中文网站 | 久草视频看看 | 美女在线免费观看视频 | 久久激情片 | av成人免费在线观看 | 亚洲高清视频在线观看免费 | 在线免费91| 一级电影免费在线观看 | 视频成人永久免费视频 | 欧美精品免费在线 | 成人国产精品一区 | 亚洲精品影视在线观看 | 日本91在线 | 亚洲日本成人网 | 国产精品青草综合久久久久99 | 婷婷丁香激情五月 | 国产综合婷婷 | 99久久日韩精品免费热麻豆美女 | 天天射天天操天天 | 亚洲精品九九 | 欧美日韩大片在线观看 | 在线观看黄 | 国产成视频在线观看 | 久草久热 | av中文字幕在线看 | 国产精品久久9 | 日韩美女免费线视频 | 天天天干天天射天天天操 | 免费大片黄在线 | 国产福利a| 狠狠色噜噜狠狠狠狠2021天天 | 一区二区不卡高清 | 99久久99久久精品国产片果冰 | 国产精品久久婷婷六月丁香 | 国产精品 国内视频 | 伊人婷婷网 | 五月天激情视频在线观看 | 黄网站免费久久 | 97超碰在线播放 | 美女视频黄免费 | 色com网| 久久久久久久福利 | 国产中文欧美日韩在线 | 美女视频久久 | 五月天久久激情 | 久久久国产视频 | 久久精品久久99精品久久 | 91福利视频免费观看 | 欧美伊人网 | 日日射av| 欧美日本一区 | 国产一级一片免费播放放a 一区二区三区国产欧美 | 日韩高清av | 久久婷婷国产色一区二区三区 | 日本乱视频| 国产香蕉视频 | 免费特级黄毛片 | 久久色视频 | 九色91在线视频 | 欧美狠狠色 | 久久久久免费观看 | a视频免费在线观看 | 久久综合精品国产一区二区三区 | 五月天亚洲精品 | 91成年视频 | 久久久久久高潮国产精品视 | 999成人免费视频 | 日韩三级免费 | 国产在线观看91 | 欧美韩国日本在线 | 国产一级视频免费看 | www.夜夜爱 | 免费看精品久久片 | 日韩视频在线不卡 | 五月天婷婷狠狠 |