多線程之使用:模擬一次宇宙戰爭來,看看多線程的其中一種使用場景。

多線程使用:模擬一次宇宙戰爭來,看看多線程的其中一種使用場景。

第一步(使用Runnable)

第一步,通過Runnable構建一個軍隊的線程,軍隊發動多次進攻,線程線程執行完便是軍隊戰爭結束
把控戰爭進度通過控制while循環實現

/**
 * @author liuzonghua
 * @Package top.maniy.util
 * @Description:
 * @date 2018/11/7 16:22
 */
public class ArmyRunnable implements Runnable{
    //volatile保證了線程可以正確的讀取其他線程寫入的值
    //可見性 JMM happens-before原型
    volatile boolean keepRunning=true;

    @Override
    public void run() {
        while (keepRunning){
            for(int i=0;i<5;i++) {
                System.out.println(Thread.currentThread().getName() + "進攻對方【" + i + "】");
                //讓出了處理時間,下次該誰進攻還不一定呢!
                Thread.yield();
            }
        }
        System.out.println(Thread.currentThread().getName()+"結束了戰鬥!");
    }
}

第二步(Thread)

Runnable使用了,我們在使用一次Thread,來表示一個關鍵人物介紹這場戰爭

public class KeyPersonThread extends Thread{
    @Override
    public void run(){
        System.out.println(Thread.currentThread().getName()+"開始了戰鬥!");
        for(int i=0;i<10;i++){
            System.out.println(Thread.currentThread().getName()+"釋放奧義");
        }
        System.out.println(Thread.currentThread().getName()+"結束戰鬥");
    }
}

第三步(戰爭舞臺)

我們要把這些軍隊和關鍵人物搬上舞臺來跑起來。
也就是線程的使用,這裏可以把舞臺也通過線程實現,便是線程調用線程的場景。
改變keepRunning 值來停止戰爭

public class Stage extends Thread {

    @Override
    public void run(){
        System.out.println("歡迎觀看多線程模擬宇宙戰爭");
        //等待幾秒吧
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("開始了");
        ArmyRunnable armyRunnableOne =new ArmyRunnable();
        ArmyRunnable armyRunnableTwo =new ArmyRunnable();

        //使用Runnable接口創建線程
        Thread armyOne = new Thread(armyRunnableOne,"弗利沙軍隊");
        Thread armyTwo = new Thread(armyRunnableTwo,"白鬍子第一軍隊");

        //啓動線程,讓軍隊開始作戰
        armyOne.start();
        armyTwo.start();

        //舞臺線程休眠,大家專心觀看軍隊廝殺
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("雙方停止戰鬥吧");
        armyRunnableOne.keepRunning =false;
        armyRunnableTwo.keepRunning=false;

        try {
            armyOne.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("激戰之中,出現boss");
        Thread boss =new KeyPersonThread();
        boss.setName("奧利哈剛的巨神兵");
        System.out.println("我要結束一切");

        armyRunnableOne.keepRunning =false;
        armyRunnableTwo.keepRunning=false;

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        boss.start();

        try {
            boss.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("一切將會結束");

        System.out.println("宇宙戰爭結束");
    }
    public static void main(String[] args){
        new Stage().start();
    }

}

知識點

一、volatile關鍵字
一旦一個共享變量(類的成員變量、類的靜態成員變量)被volatile修飾之後,那麼就具備了兩層語義:

1)保證了不同線程對這個變量進行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。

2)禁止進行指令重排序。
二、Thread.yield();
當調用Thread.yield()方法時,會給線程調度器一個當前線程願意讓出CPU使用的暗示,但是線程調度器可能會忽略這個暗示.
說白話,就是線程暫停允許執行其他線程(包括自己),我把球丟在空中,大家一起搶。
三、t.join();
t.join()方法會使所有線程都暫停並等待t的執行完畢。這裏等待軍隊線程結束後,在執行關鍵人物線程。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章