日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

java

Java——多线程学习

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

參考文章:https://www.jb51.net/article/127443.htm


1、先來說下多線程的概念:
  • 多線程:一個進程如果有多條執行路徑,則稱為多線程程序。

簡單來說就是原來是一條路徑執行(只有一個CPU的情況下),現在是多條路徑執行。就相當于一條公路,原來是一條路,為提高使用效率,充分使用這條道路,在路中間加了一些線,變成了多車道(仍是單向的)。

2、多線程的優點:
  • 資源利用率更高
  • 程序設計在某些情況下更簡單
  • 程序響應更快
  • 1、關于資源利用率更高:

    • 假如一個應用程序需要從磁盤中讀取和處理文件。從磁盤讀取一個文件需要5秒,處理一個文件需要2秒。那么處理這樣的兩個文件則需要
    5秒讀取文件A 2秒處理文件A 5秒讀取文件B 2秒處理文件B --------------------- 總共需要14
    • 從磁盤中讀取文件的時候,大部分的CPU時間用于等待磁盤去讀取數據。在這段時間里CPU處于空閑狀態。它可以做一些別的事情。通過改變操作的順序,就能夠更好的使用CPU資源。看下面的順序:
    5秒讀取文件A 5秒讀取文件B + 2秒處理文件A 2秒處理文件B --------------------- 總共需要12
    • CPU等待第一個文件被讀取完。然后開始讀取第二個文件。當第二文件在被讀取的時候(IO讀取,CPU處于空閑),CPU會去處理第一個文件。在等待磁盤讀取文件的時候,CPU大部分時間是空閑的。

    總的說來,CPU能夠在等待IO的時候做一些其他的事情。這個不一定就是磁盤IO。它也可以是網絡的IO,或者用戶輸入。通常情況下,網絡和磁盤的IO比內存的IO慢的多。

    2、程序設計更簡單:

    • 在單線程應用程序中,如果你想編寫程序手動處理上面所提到的讀取和處理的順序,你必須記錄每個文件讀取和處理的狀態。
    • 相反,你可以啟動兩個線程,每個線程分別運行一個文件的讀取和處理。線程會在等待磁盤讀取文件的過程中被阻塞。在等待的時候,其他的線程能夠使用CPU去處理已經讀取完的文件。
    • 其結果就是,磁盤總是在繁忙地讀取不同的文件到內存中。這會帶來磁盤和CPU利用率的提升。而且每個線程只需要記錄一個文件,因此這種方式也很容易編程實現。

    3、 程序響應更快:

    • 如果一個請求需要占用大量的時間來處理,在這段時間內客戶端就無法發送新的請求給服務端。只有服務器在監聽的時候,請求才能被接收。
    • 另一種設計是,監聽線程把請求傳遞給工作者線程(worker thread),然后立刻返回去監聽。而工作者線程則能夠處理這個請求并發送一個回復給客戶端。
    • 這樣就大大提高了程序的響應速度。

    以下是一個多線程實現買票的例子:


    1、案例需求

    • 某電影院目前正在上映國產大片,共有100張票,而它有3個窗口賣票,請設計一個程序模擬該電影院賣票。

    實現步驟:

  • 定義一個類SellTicket實現Runnable接口,里面定義一個成員變量:private int tickets = 100;
  • 在SellTicket類中重寫run()方法實現賣票,代碼步驟如下
  • 判斷票數大于0,就賣票,并告知是哪個窗口賣的
  • 賣了票之后,總票數要減1
  • 票沒有了,也可能有人來問,所以這里用死循環讓賣票的動作一直執行
  • 定義一個測試類SellTicketDemo,里面有main方法,代碼步驟如下
  • 創建SellTicket類的對象
  • 創建三個Thread類的對象,把SellTicket對象作為構造方法的參數,并給出對應的窗口名稱
  • 啟動線程
  • 代碼實現:

    public class SellTicket implements Runnable {private int tickets = 100;//在SellTicket類中重寫run()方法實現賣票,代碼步驟如下@Overridepublic void run() {while (true) {if (tickets > 0) {System.out.println(Thread.currentThread().getName() + "正在出售第" +tickets + "張票");tickets--;}}} } public class SellTicketDemo {public static void main(String[] args) {//創建SellTicket類的對象SellTicket st = new SellTicket();//創建三個Thread類的對象,把SellTicket對象作為構造方法的參數,并給出對應的窗口名稱Thread t1 = new Thread(st,"窗口1");Thread t2 = new Thread(st,"窗口2");Thread t3 = new Thread(st,"窗口3");//啟動線程t1.start();t2.start();t3.start();} }

    執行結果:

    可以看到票數出現了異常,出現了重復的票,甚至還有可能出現負數的票。

    2、賣票案例的問題

    問題產生原因:

    • 線程執行的隨機性導致的

    詳細解析:

    相同的票出現了多次:

    public class SellTicket implements Runnable {private int tickets = 100;@Overridepublic void run() {while (true) {//tickets = 100;//t1,t2,t3//假設t1線程搶到CPU的執行權if (tickets > 0) {//通過sleep()方法來模擬出票時間try {Thread.sleep(100);//t1線程休息100毫秒//t2線程搶到了CPU的執行權,t2線程就開始執行,執行到這里的時候,t2線程休息100毫秒//t3線程搶到了CPU的執行權,t3線程就開始執行,執行到這里的時候,t3線程休息100毫秒} catch (InterruptedException e) {e.printStackTrace();}//假設線程按照順序醒過來//t1搶到CPU的執行權,在控制臺輸出:窗口1正在出售第100張票System.out.println(Thread.currentThread().getName() + "正在出售第"+tickets + "張票");//t2搶到CPU的執行權,在控制臺輸出:窗口2正在出售第100張票//t3搶到CPU的執行權,在控制臺輸出:窗口3正在出售第100張票tickets--;//如果這三個線程還是按照順序來,這里就執行了3次--的操作,最終票就變成了97}}} }

    出現了負數的票:

    public class SellTicket implements Runnable {private int tickets = 100;public void run() {while (true) {//tickets = 1;//t1,t2,t3//假設t1線程搶到CPU的執行權if (tickets > 0) {//通過sleep()方法來模擬出票時間try {Thread.sleep(100);//t1線程休息100毫秒//t2線程搶到了CPU的執行權,t2線程就開始執行,執行到這里的時候,t2線程休息100毫秒//t3線程搶到了CPU的執行權,t3線程就開始執行,執行到這里的時候,t3線程休息100毫秒} catch (InterruptedException e) {e.printStackTrace();}//假設線程按照順序醒過來//t1搶到了CPU的執行權,在控制臺輸出:窗口1正在出售第1張票//假設t1繼續擁有CPU的執行權,就會執行tickets--;操作,tickets = 0;//t2搶到了CPU的執行權,在控制臺輸出:窗口1正在出售第0張票//假設t2繼續擁有CPU的執行權,就會執行tickets--;操作,tickets = -1;//t3搶到了CPU的執行權,在控制臺輸出:窗口3正在出售第-1張票//假設t2繼續擁有CPU的執行權,就會執行tickets--;操作,tickets = -2;System.out.println(Thread.currentThread().getName() + "正在出售第" +tickets + "張票");tickets--;}}} }

    3、同步代碼塊解決數據安全問題

    安全問題出現的條件:

  • 是多線程環境
  • 有共享數據
  • 有多條語句操作共享數據
  • 如何解決多線程安全問題呢?

    • 基本思想:讓程序沒有安全問題的環境

    如何實現?

    • 把多條語句操作共享數據的代碼給鎖起來,讓任意時刻只能有一個線程執行即可。

    Java提供了同步代碼塊的方式來解決:

    同步代碼塊格式:

    synchronized(任意對象) {多條語句操作共享數據的代碼 }

    synchronized(任意對象):就相當于給代碼加鎖了,任意對象就可以看成是一把鎖。

    同步的好處和弊端:

    • 好處:解決了多線程的數據安全問題
    • 弊端:當線程很多時,因為每個線程都會去判斷同步上的鎖,這是很耗費資源的,無形中會降低程序的運行效率。

    代碼演示:

    package sellticket;public class SellTicket implements Runnable {private int tickets = 100;private Object obj = new Object();//使用同一個對象加鎖,相當于使用同一把鎖@Overridepublic void run() {while (true) {//tickets = 100;//t1,t2,t3//假設t1搶到了CPU的執行權//假設t2搶到了CPU的執行權synchronized (obj) {//t1進來后,就會把這段代碼給鎖起來if (tickets > 0) {try {Thread.sleep(100);//t1休息100毫秒} catch (InterruptedException e) {e.printStackTrace();}//窗口1正在出售第100張票System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + " 張票");tickets--; //tickets = 99;}}//t1出來了,這段代碼的鎖就被釋放了}} } public class SellTicketDemo {public static void main(String[] args) {SellTicket st = new SellTicket();Thread t1 = new Thread(st, "窗口1");Thread t2 = new Thread(st, "窗口2");Thread t3 = new Thread(st, "窗口3");t1.start();t2.start();t3.start();} }

    4、同步方法解決數據安全問題

    同步方法:就是把synchronized關鍵字加到方法上。

    修飾符 synchronized 返回值類型 方法名(方法參數) {方法體; }

    同步方法的鎖對象是:this

    靜態同步方法:

    • 同步靜態方法:就是把synchronized關鍵字加到靜態方法上

    例:

    同步方法:

    private synchronized void sellTicket() {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "張票");tickets--;}}

    靜態同步方法:

    private static synchronized void sellTicket() {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在出售第" +tickets + "張票");tickets--;}} }

    5、Lock鎖

    雖然我們可以理解同步代碼塊和同步方法的鎖對象問題,但是我們并沒有直接看到在哪里加上了鎖,在哪里釋放了鎖,為了更清晰的表達如何加鎖和釋放鎖,JDK5以后提供了一個新的鎖對象Lock

    • Lock是接口不能直接實例化,采用它的實現類ReentrantLock來實例化。

    ReentrantLock構造方法:


    加鎖解鎖方法:


    例:

    public class SellTicket implements Runnable {private int tickets = 100;private Lock lock = new ReentrantLock();@Overridepublic void run() {while (true) {try {lock.lock();if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + " 張票");tickets--;}} finally {lock.unlock();}}} }

    關于java多線程的總結暫時就這些了。

    總結

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

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

    主站蜘蛛池模板: 国产不雅视频 | 少妇情理伦片丰满午夜在线观看 | 久久欧美 | 久久免费黄色网址 | 灌满闺乖女h高h调教尿h | 中日韩在线观看 | 91pron在线| 欧美精品欧美精品系列 | 4444亚洲人成无码网在线观看 | a天堂中文 | 99精品国自产在线 | 日韩欧美亚洲国产精品字幕久久久 | 欧美激情性做爰免费视频 | 极品少妇xxxx精品少妇偷拍 | 国产一级免费av | 欧美精品一区二区三区在线播放 | 亚洲中文字幕无码一区二区三区 | 精品久久久久久无码人妻 | 黄色三级在线 | 天天看天天摸天天操 | 精品久久蜜桃 | 亚洲欧美网站 | 淫语对白| 婷婷99 | 日本三级中国三级99人妇网站 | 一区二区三区高清在线观看 | 我要看免费毛片 | 色综合激情网 | 亚洲成人乱码 | 爽爽影院在线免费观看 | 青娱乐最新官网 | 男人撒尿视频xvideos | 精品亚洲国产成av人片传媒 | 精品久久久久久久无码 | 丝袜ol美脚秘书在线播放 | 日本黄图| 绿帽av | 天啪| 国产二级片 | 免费国产在线观看 | 国产在线播放一区二区三区 | 五月在线视频 | 国产精品久久婷婷六月丁香 | 久久精品一区二区在线观看 | 三级黄色片免费观看 | 亚洲精品小视频在线观看 | 尤物视频在线观看 | 亚洲一区二区免费在线观看 | 日本在线中文字幕专区 | 亚洲三级小视频 | 亚洲大尺度在线 | 成人a√| 国产免费内射又粗又爽密桃视频 | 亚洲精品成av人片天堂无码 | 日本天堂免费a | www.色婷婷.com | 无码人妻精品一区二区三区99不卡 | 色呦呦 | 亚州综合网 | 欧美日韩91 | 欧美大片黄色 | 欧美精品成人一区二区三区四区 | 国产三级麻豆 | 久久精品国产亚洲av久 | 制服诱惑一区二区三区 | 成人福利小视频 | 久久春色 | 手机在线免费看av | 日本丰满少妇裸体自慰 | 7777久久亚洲中文字幕 | 国产精品一区二区三区免费观看 | 成人涩涩网站 | 青青草原伊人网 | 亚洲高清自拍 | 茄子av| 国产日产精品一区二区三区四区 | 粉嫩久久99精品久久久久久夜 | h视频免费在线观看 | hitomi一区二区三区精品 | 男人天堂成人 | 国产极品一区二区 | 日本在线视频www | 成人吃奶视频 | 成人软件在线观看 | 青娱乐在线视频免费观看 | 久久久丁香 | 亚洲欧美另类中文字幕 | 国产美女自拍视频 | 欧美亚洲一区二区三区四区 | 大尺度在线观看 | 毛片的网址 | 久久精品一区二区三区黑人印度 | 三级视频网站 | 99热中文 | 黄色一级网站 | 男人的天堂伊人 | 欧洲亚洲国产精品 | 亚洲一级特黄 | 漂亮人妻洗澡被公强 日日躁 |