4.10多线程--习题

/**
 * 4.10多线程--习题一(购票)
 * 1. 创建新线程的内部代码需要考虑线程安全问题
 * 2. int amount = window.sell(randomAmount()); 与 amountList.add(amount); 是两个不同的对象,他们的组合不存在安全问题
 * 3. 通过 Thread.sleep(500); 来模拟现实中可能发生的上下文切换,如果没有这段代码,因为逻辑代码太少,很可能不发生上下文切换,也就没法看到想要的效果
 * 4. Vector Random 是线程安全的
 * 5. amountList.stream().mapToInt(i->i).sum())
 */
public class Demo1 {

    public static void main(String[] args) {
        //模拟多人买票
        TicketWindow window = new TicketWindow(20000);

        // 2000 人同时买票
        List threadList = new ArrayList<>();//全部线程
        List amountList = new Vector<>();//卖出票数
        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());//需要考虑线程安全问题
                amountList.add(amount);//需要考虑线程安全问题
            });
            threadList.add(thread);
            thread.start();
        }
        for (Thread thread : threadList) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //所有线程结束后,检验是否正确
        System.out.println("余票数量:"+window.getCount());
        System.out.println("卖出的票数:"+amountList.stream().mapToInt(i->i).sum());
        System.out.println("总票数:"+(window.getCount() + amountList.stream().mapToInt(i->i).sum()));
    }

    // Random 是线程安全的
    static Random random = new Random();
    //随机 1-5
    public static int randomAmount(){
        return random.nextInt(5)+1;
    }
}
//售票窗口
class TicketWindow{
    private int count;//余票数量

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

    public int getCount() {
        return count;
    }
    //售票,购买数量
    public synchronized int sell(int amount){
        if(this.count >= amount){
            this.count -= amount;
            return amount;
        } else {
            return 0;
        }
    }
}
/**
 * 4.10多线程--习题二(转账)
 * 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();
    //随机 1-100
    public static int randomAmount(){
        return random.nextInt(100)+1;
    }
}

//账号
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;
    }

    //转账
    public void transfer(Account target, int amount){
        synchronized (Account.class){
            if(this.money >= amount){
                this.setMoney(this.money - amount);
                target.setMoney(target.getMoney() + amount);
            }
        }
    }
}

你可能感兴趣的:(4.10多线程--习题)