1. 程式人生 > 其它 >【狂神說Java】併發問題、龜兔賽跑(僅發現問題,未處理)

【狂神說Java】併發問題、龜兔賽跑(僅發現問題,未處理)

併發問題

public class MoreTreads implements Runnable{
    // 多執行緒同時操作同一個物件
    // 買火車票的例子
    private int ticketNums = 10;

    @Override
    public void run() {
        while(true){
            if(ticketNums<=0){
                break;
            }
            // 模擬延時
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 獲取當前執行緒名字Thread.currentThread().getName()
            System.out.println(Thread.currentThread().getName()+"第"+(ticketNums--)+"張票");
        }
    }

    public static void main(String[] args) {
        MoreTreads moreTreads = new MoreTreads();
        // 匿名
        new Thread(moreTreads,"A").start();
        new Thread(moreTreads,"B").start();
        new Thread(moreTreads,"C").start();
    }
}

多執行緒同時操作同一個物件存在問題,資料紊亂,執行緒不安全,如圖:

龜兔賽跑

列印進度條,/r回到開頭

System.out.print("=/r");
System.out.print("====/r");

龜兔賽跑程式碼

public class Race implements Runnable{
    private static String winner;
    private static int distance;

    public Race(int num) {
        this.distance = num;
    }

    @Override
    public void run() {
        for (int i = 0; i < distance; i++) {
            if (gameOver()){
                break;  // 判斷有沒有到終點
            }
            position(i); // 列印當前位置
            try {
                Thread.sleep(10); // 兔子速度 ,走一步停 10
                if(Thread.currentThread().getName() == "龜"){
                    Thread.sleep(90);  // 烏龜速度,走一步停 10+90
                }
                if (Thread.currentThread().getName() == "兔" && i == distance/2){
                    Thread.sleep(distance * 90 + 1);  // 兔子在一半路程會睡覺
                    // 50*10 = 500 兔子贏,烏龜才走了5步,讓烏龜贏要讓烏龜在所有時間走45步,也就是讓兔子等45*100ms以上
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
    }

    private boolean gameOver(){
        // 判斷有沒有勝利者
        if (winner!=null){
            return true;
        }
        return false;
    }


    public void position(int num){
        // 位於賽道位置
        for (int i = 0; i < num; i++) {
            System.out.print("=");
        }

        // 獲取執行緒名字
        System.out.print(Thread.currentThread().getName()+"\r");
        if (num == distance-1){
            System.out.println(Thread.currentThread().getName()+"勝利");
            winner = Thread.currentThread().getName();
        }
    }

    public static void main(String[] args) {
        Race race = new Race(50);// 在同一個賽道跑,同一個物件
        new Thread(race,"兔").start();
        new Thread(race,"龜").start();
    }
}