當前位置:網站首頁>多線程詳解第2講:線程實現(重點,快速學會

多線程詳解第2講:線程實現(重點,快速學會

2021-08-20 01:11:21 天天熬夜敲代碼

    //run方法線程體

    for(int i = 0; i < 20 ; i++){

        System.out.println("我在看代碼---"+i);

    }



}

public static void main(String[] args) {

    //main線程,主線程



    //創建一個線程對象

    TestThread1 testThread1 = new TestThread1();



    //調用start()方法開啟線程,執行run方法

    testThread1.start();

    for(int i = 0; i < 20; i++){

        System.out.println("我在學習多線程---"+i);

    }

}

}




**執行結果**  

![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392736786280.jpg)  

**主線程和run方法線程交替執行。**



### [](https://gitee.com/vip204888/java-p7)3、案例:下載圖片



**代碼**




     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.

package com.kaung.demo01;

import org.apache.commons.io.FileUtils;

import java.io.File;

import java.io.IOException;

import java.net.URL;

//練習Thread ,實現多線程同步下載圖片

public class TestThread2 extends Thread{

private String url; //網絡圖片地址

private String name; //保存的文件名

public TestThread2(String url,String name){

    this.url=url;

    this.name=name;

}

//下載圖片線程執行體

@Override

public void run() {

    WebDownloader webDownloader = new WebDownloader();

    webDownloader.downloader(url,name);

    System.out.println("下載了文件名為:"+name);

}



public static void main(String[] args) {

    TestThread2 t1 = new TestThread2("https://public-cdn-oss.mosoteach.cn/books/mobile/[email protected]","1.jpg");

    TestThread2 t2 = new TestThread2("https://public-cdn-oss.mosoteach.cn/books/mobile/[email protected]","2.jpg");

    TestThread2 t3 = new TestThread2("https://public-cdn-oss.mosoteach.cn/books/mobile/[email protected]","3.jpg");

    //先下載t1

    t1.start();

    //然後t1

    t2.start();

    //最後t3

    t3.start();

}

}

//下載器

class WebDownloader{

//下載方法

public void downloader(String url,String name){

    try {

        FileUtils.copyURLToFile(new URL(url),new File(name));

    } catch (IOException e) {

        e.printStackTrace();

        System.out.println("IO异常,downloader方法出現异常");

    }

}

}




**運行截圖**



![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392737129605.jpg)  

我們開啟了三個線程,這三個線程並不是按序執行的,誰先搶奪到了時間,誰先執行。



驗證了結論:**在一個進程中,如果開辟了多個線程,線程的運行由調度器安排調度,調度器是與操作系統緊密相關的,先後順序是不能認為的幹預的。**



### [](https://gitee.com/vip204888/java-p7)4、實現Runnable接口



**步驟**



1.  **定義MyRunnable類實現Runnable接口**

    

2.  **實現run()方法,編寫線程執行體**

    

3.  **創建線程對象,調用start()方法啟動線程**

    



**代碼**




     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

package com.kaung.demo01;

public class TestThread3 implements Runnable{

@Override

public void  run(){

    //run方法線程體

    for(int i = 0; i < 20 ; i++){

        System.out.println("我在看代碼---"+i);

    }



}

public static void main(String[] args) {



    //創建runable接口的實現類對象

    TestThread3 testThread3 = new TestThread3();

    //創建線程對象,通過線程對象來開啟我們的線程,代理

    Thread thread = new Thread(testThread3);

    thread.start();



    for(int i = 0; i < 200; i++){

        System.out.println("我在學習多線程---"+i);

    }

}

}




**推薦使用Runnable對象,因為Java單繼承的局限性**



### [](https://gitee.com/vip204888/java-p7)5、小結



**繼承Thread類**



*   **子類繼承Thread類具備多線程能力**

*   **啟動線程:子類對象. start()**

*   不建議使用:避免OOP單繼承局限性



**實現Runable接口**



*   **實現接口Runnable具有多線程能力**

*   **啟動線程:傳入目標對象+Thread對象.start()**

*   推薦使用:避免單繼承局限性,靈活方便,方便同一個對象被多個線程使用



### [](https://gitee.com/vip204888/java-p7)6、初始並發問題



**代碼**




     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.

package com.kaung.demo01;

//多個線程同時操作一個對象

//買火車票的例子

//發現問題 : 多個線程操作同一個資源的情况下,線程不安全,數據紊亂。

public class TestThread4 implements Runnable {

private int ticketNums = 10;

@Override

public void run() {

    while(true){

        if((ticketNums<=0)){

            break;

        }

        //模擬延時

        try {

            Thread.sleep(200);

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        System.out.println(Thread.currentThread().getName()+"--->拿到了第"+ticketNums-- +"票");

    }

}



public static void main(String[] args) {

    TestThread4 ticket = new TestThread4();



    new Thread(ticket,"小明").start();

    new Thread(ticket,"老師").start();

    new Thread(ticket,"黃牛黨").start();

}

}




**運行截圖**  

![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392739933656.jpg)  

**發現問題 : 多個線程操作同一個資源的情况下,線程不安全,數據紊亂。**



### [](https://gitee.com/vip204888/java-p7)7、龜兔賽跑



![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392741433321.jpg)  

**代碼模擬**




     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

package com.kaung.demo01;

//模擬龜兔賽跑

public class Race implements Runnable{

private static String winner;

@Override

public void run() {

    for (int i = 0; i <= 100; i++) {



        //模擬兔子休息

        if(Thread.currentThread().getName().equals("兔子")&&i%10==0) {

            try {

                Thread.sleep(10);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }

        }

        //判斷比賽是否結束

        boolean flag = gameOver(i);

        if(flag){

            break;

        }

        System.out.println(Thread.currentThread().getName()+"--->跑了"+i+"步");

    }

}

//判斷是否完成比賽

private boolean gameOver(int steps){

    //判斷是否有勝利者

    if(winner!=null) //已經有勝利者了

    {

        return true;

    }

    if(steps>=100){

        winner = Thread.currentThread().getName();

        System.out.println("winner is "+winner);

        return true;

    }

    return false;

}



public static void main(String[] args) {

    Race race = new Race();

    new Thread(race,"兔子").start();

    new Thread(race,"烏龜").start();

}

}




### [](https://gitee.com/vip204888/java-p7)8、實現Callable接口(了解即可)



![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392743252290.jpg)



### [](https://gitee.com/vip204888/java-p7)9、靜態代理



![在這裏插入圖片描述](https://s2.51cto.com/images/20210820/1629392744765239.jpg)  

**模式總結**



*   真實對象和代理對象都要實現同一個接口

*   代理對象要代理真實對象



**好處**



*   代理對象可以做很多真實對象做不了的事情

*   真實對象專注做自己的事情



**代碼**




     
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.

import sun.plugin2.main.client.WDonatePrivilege;

//靜態代理模式總結

//真實對象和代理對象都要實現同一個接口

//代理對象要代理真實對象

//好處

//代理對象可以做很多真實對象做不了的事情

//真實對象專注做自己的事情

public class StaticProxy {

public static void main(String[] args) {

    You you = new You();



    new Thread(()-> System.out.println("我愛你")).start();



    new WeddingCompany(new You()).HappyMarry();



}

}

interface Marry{

void HappyMarry();

}

//真實角色,你去結婚

class You implements Marry {

@Override

public void HappyMarry() {

    System.out.println("我要結婚了,超開心");

}

}

//代理對象,幫助你結婚

class WeddingCompany implements Marry {

//代理誰--> 真實目標角色

private Marry target; //目標對象



public WeddingCompany(Marry target) {

    this.target = target;

}



@Override

public void HappyMarry() {

    brfore();

    this.target.HappyMarry(); //這就是真實對象

    after();

總目錄展示

該筆記共八個節點(由淺入深),分為三大模塊。

高性能。 秒殺涉及大量的並發讀和並發寫,因此支持高並發訪問這點非常關鍵。該筆記將從設計數據的動靜分離方案、熱點的發現與隔離、請求的削峰與分層過濾、服務端的極致優化這4個方面重點介紹。

一致性。 秒殺中商品减庫存的實現方式同樣關鍵。可想而知,有限數量的商品在同一時刻被很多倍的請求同時來减庫存,减庫存又分為“拍下减庫存”“付款减庫存”以及預扣等幾種,在大並發更新的過程中都要保證數據的准確性,其難度可想而知。因此,將用一個節點來專門講解如何設計秒殺减庫存方案。

高可用。 雖然介紹了很多極致的優化思路,但現實中總難免出現一些我們考慮不到的情况,所以要保證系統的高可用和正確性,還要設計一個PlanB來兜底,以便在最壞情况發生時仍然能够從容應對。筆記的最後,將帶你思考可以從哪些環節來設計兜底方案。


篇幅有限,無法一個模塊一個模塊詳細的展示(這些要點都收集在了這份《高並發秒殺頂級教程》裏),覺得有需要的碼友們,麻煩各比特轉發一下(可以幫助更多的人看到喲!) 點這裏,即可獲得免費下載的方式!!

由於內容太多,這裏只截取部分的內容。需要這份《高並發秒殺頂級教程》的小夥伴,麻煩各比特幫忙點贊分享支持一下(可以幫助更多的人看到喲!)

版權聲明
本文為[天天熬夜敲代碼]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2021/08/20210820011120839c.html

隨機推薦