4.10多線程--習(xí)題

/**
 * 4.10多線程--習(xí)題一(購(gòu)票)
 * 1. 創(chuàng)建新線程的內(nèi)部代碼需要考慮線程安全問(wèn)題
 * 2. int amount = window.sell(randomAmount()); 與 amountList.add(amount); 是兩個(gè)不同的對(duì)象,他們的組合不存在安全問(wèn)題
 * 3. 通過(guò) Thread.sleep(500); 來(lái)模擬現(xiàn)實(shí)中可能發(fā)生的上下文切換,如果沒(méi)有這段代碼,因?yàn)檫壿嫶a太少,很可能不發(fā)生上下文切換,也就沒(méi)法看到想要的效果
 * 4. Vector Random 是線程安全的
 * 5. amountList.stream().mapToInt(i->i).sum())
 */
public class Demo1 {

    public static void main(String[] args) {
        //模擬多人買(mǎi)票
        TicketWindow window = new TicketWindow(20000);

        // 2000 人同時(shí)買(mǎi)票
        List<Thread> threadList = new ArrayList<>();//全部線程
        List<Integer> amountList = new Vector<>();//賣(mài)出票數(shù)
        for (int i = 0; i < 2000; i++) {
            Thread thread = new Thread(()->{
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                int amount = window.sell(randomAmount());//需要考慮線程安全問(wèn)題
                amountList.add(amount);//需要考慮線程安全問(wèn)題
            });
            threadList.add(thread);
            thread.start();
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //所有線程結(jié)束后,檢驗(yàn)是否正確
        System.out.println("余票數(shù)量:"+window.getCount());
        System.out.println("賣(mài)出的票數(shù):"+amountList.stream().mapToInt(i->i).sum());
        System.out.println("總票數(shù):"+(window.getCount() + amountList.stream().mapToInt(i->i).sum()));
    }

    // Random 是線程安全的
    static Random random = new Random();
    //隨機(jī) 1-5
    public static int randomAmount(){
        return random.nextInt(5)+1;
    }
}
//售票窗口
class TicketWindow{
    private int count;//余票數(shù)量

    public TicketWindow(int count) {
        this.count = count;
    }

    public int getCount() {
        return count;
    }
    //售票,購(gòu)買(mǎi)數(shù)量
    public synchronized int sell(int amount){
        if(this.count >= amount){
            this.count -= amount;
            return amount;
        } else {
            return 0;
        }
    }
}
/**
 * 4.10多線程--習(xí)題二(轉(zhuǎn)賬)
 * 1.synchronized (Account.class) 不推薦使用
 */
public class Demo2 {

    public static void main(String[] args) throws InterruptedException {
        Account a = new Account(1000);
        Account b = new Account(1000);

        Thread t1 = new Thread(()->{
            for (int i = 0; i < 500; i++) {
                a.transfer(b,randomAmount());
            }
        },"t1");
        Thread t2 = new Thread(()->{
            for (int i = 0; i < 500; i++) {
                b.transfer(a,randomAmount());
            }
        },"t2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(a.getMoney());
        System.out.println(b.getMoney());
        System.out.println(a.getMoney() + b.getMoney());
    }

    // Random 是線程安全的
    static Random random = new Random();
    //隨機(jī) 1-100
    public static int randomAmount(){
        return random.nextInt(100)+1;
    }
}

//賬號(hào)
class Account{
    private int money;//余額

    public Account(int money) {
        this.money = money;
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    //轉(zhuǎn)賬
    public void transfer(Account target, int amount){
        synchronized (Account.class){
            if(this.money >= amount){
                this.setMoney(this.money - amount);
                target.setMoney(target.getMoney() + amount);
            }
        }
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容