1. 程式人生 > 遊戲攻略 >《永劫無間》鋼鐵俠MK3捏臉資料分享

《永劫無間》鋼鐵俠MK3捏臉資料分享

Java多執行緒基礎(1)

學習筆記為手打,教程為 【狂神說Java】多執行緒詳解

執行緒基礎

1. 執行緒就是獨立執行路徑

2. 在程式執行時,及時沒有自己建立執行緒,後臺夜會有多個執行緒,如主執行緒,gc執行緒

3. main()稱之為主執行緒,為系統的入口,用於執行整個程式

4. 在一個程序中,如果開闢多個執行緒,執行緒的運作有排程器安排排程,排程器是與作業系統緊密相關的,先後順序是不能人為的干預的

5. 對同一份資源操作時,會存在資源搶奪問題,需要加入併發控制

6. 執行緒會帶來額外的開銷,如cpu排程時間,併發控制開銷

7. 每個執行緒在自己的工作記憶體互動,記憶體控制不當會造成資料的不一致

執行緒建立

三種建立方式

Thread class

子類繼承Thread具備多執行緒功能

啟動執行緒:子類物件.start()

OOP單繼承侷限性

public class ThreadsDemo2 extends Thread{



    private String url;  /*網路圖片位置*/



    private String name;  /*檔名稱*/


    public ThreadsDemo2(String url, String name) {
        this.url = url;
        this.name = name;


    }

    //下載圖片的執行體
    @Override
    public void run() {

        WebDownloader webDownloader = new WebDownloader();
        try {
            webDownloader.downloader(url,name);
            System.out.println("下載圖片為"+ name);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        String url1 = "https://img0.baidu.com/it/u=4156074303,275806129&fm=26&fmt=auto&gp=0.jpg";
        String url2 = "https://img1.baidu.com/it/u=1684000154,1654099979&fm=26&fmt=auto&gp=0.jpg";
        String url3 = "https://img0.baidu.com/it/u=1506294494,3075748085&fm=26&fmt=auto&gp=0.jpg";

        String name1 = "頭像1.jpg";
        String name2 = "頭像2.jpg";
        String name3 = "頭像3.jpg";

        ThreadsDemo2 t1= new ThreadsDemo2(url1,name1);
        ThreadsDemo2 t2= new ThreadsDemo2(url1,name2);
        ThreadsDemo2 t3= new ThreadsDemo2(url1,name3);
        t1.start();
        t2.start();
        t3.start();
    }
}

/**
 * 下載器
 */
class WebDownloader {
    public void downloader(String url, String name) throws IOException {
        FileUtils.copyURLToFile(new URL(url), new File(name));
    }
}

第一次執行

第二次執行

結論:兩次執行的次序並不按順序,可知三個執行緒是並行的。

Runnable interface

實現Runnable具有多執行緒能力

啟動執行緒:傳入目標物件+thread物件.start()

靈活,方便物件被多個執行緒使用

public class ThreadsDemo3  implements Runnable{

    @Override
    public void run() {
        //run()方法執行緒體
        for (int i = 0; i < 200; i++) {
            System.out.println("========run"+i);
        }
    }

    public static void main(String[] args) {

        ThreadsDemo3 t1 = new ThreadsDemo3();
        new Thread(t1).start();

        for (int i = 0; i < 2000; i++) {
            System.out.println("======main"+i);
        }
    }
}


Callable interface (暫時瞭解 21/08/23)

public class ThreadsDemo6 implements Callable<Boolean> {
    private String url;  /*網路圖片位置*/

    private String name;  /*檔名稱*/

    public ThreadsDemo6(String url1, String name1) {
        this.url = url1;
        this.name = name1;
    }


    @Override
    public Boolean call() throws Exception {
        WebDownloader webDownloader = new WebDownloader();
        try {
            webDownloader.downloader(url,name);
            System.out.println("下載圖片為"+ name);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String url1 = "https://img0.baidu.com/it/u=4156074303,275806129&fm=26&fmt=auto&gp=0.jpg";
        String url2 = "https://img1.baidu.com/it/u=1684000154,1654099979&fm=26&fmt=auto&gp=0.jpg";
        String url3 = "https://img0.baidu.com/it/u=1506294494,3075748085&fm=26&fmt=auto&gp=0.jpg";

        String name1 = "頭像1.jpg";
        String name2 = "頭像2.jpg";
        String name3 = "頭像3.jpg";

        ThreadsDemo6 t1= new ThreadsDemo6(url1,name1);
        ThreadsDemo6 t2= new ThreadsDemo6(url1,name2);
        ThreadsDemo6 t3= new ThreadsDemo6(url1,name3);

        //建立執行服務
        ExecutorService executorService= Executors.newFixedThreadPool(3);

        //提交執行
        Future<Boolean> r1 =executorService.submit(t1);
        Future<Boolean> r2 =executorService.submit(t2);
        Future<Boolean> r3 =executorService.submit(t3);

        //獲取結果

        Boolean rs1 = r1.get();
        Boolean rs2 = r2.get();
        Boolean rs3 = r3.get();

        //關閉服務
        executorService.shutdownNow();
    }
}

執行緒併發

發現問題

多個執行緒操作同一個資源識,執行緒不安全,資料紊亂

public class ThreadsDemo4 implements Runnable{
    private int ticketNum = 10;
    @Override
    public void run() {

        while (true){
            if (ticketNum <1 ) {
                break;
            }
            System.out.println( Thread.currentThread().getName()+ "===>拿了第"+ticketNum-- +"票");
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        ThreadsDemo4 ticket = new ThreadsDemo4();
        new Thread(ticket, "XiaoMing").start();
        new Thread(ticket, "XiaoHong").start();
        new Thread(ticket, "HuangNiu").start();
    }
}

加深對多執行緒的印象——模擬龜兔賽跑

public class ThreadsDemo5 implements Runnable {
    //勝利者
   private static String winner;
   //跑道長度
    private static int RUNWAY_LENGTH  = 50;
    //遊戲結束標誌
    boolean gameOver(int i){
        //勝者唯一
        if (winner!=null){
            return true;
        }

        if( i >= RUNWAY_LENGTH){
            winner = Thread.currentThread().getName();
            System.out.println("===比賽結束==="+"\n"+winner+"-->獲得了勝利");

            return true;
        }
        return false;
    }
    @Override
    public void run() {


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

            boolean flag = gameOver(i);
            if (flag) {
                break;
            }
            String name = Thread.currentThread().getName();

            System.out.println(name + "-->已經跑了" + i + "米");

            //兔子跑的快
            if ("兔子".equals(name)){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //烏龜爬的慢
            if ("烏龜".equals(name)) {
                System.out.println("加油!!!!");
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //兔子半路睡著
             if ("兔子".equals(name) && i == RUNWAY_LENGTH/2){
                System.out.println("怎麼能睡覺呢?\n");
                try {
                    Thread.sleep(60);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }


        }

    }

    public static void main(String[] args) {

        ThreadsDemo5 race = new ThreadsDemo5();
        new Thread(race,"兔子").start();
        new Thread(race,"烏龜").start();
    }

}