8.2、线程同步(不安全样例改良)

synchronized对象所

用在方法上锁的是this或class
利用synchronized块来自定义锁的对象
一定要判断好要锁住哪个对象


样例一,用在方法上锁住this对象

package com.example.demo.thread;

/**
 * @projectName: demo
 * @package: com.example.demo.thread
 * @className: AsyncTest1
 * @author:
 * @description: 线程不安全示例1
 * @date: 2021/12/7 23:54
 */
public class AsyncTest1 {
    public static void main(String[] args) {
        Ticket ticket = new Ticket();
        new Thread(ticket, "程序员").start();
        Thread thread1 = new Thread(ticket, "黄牛");
        thread1.setPriority(1);
        Thread thread = new Thread(ticket, "学生");
        thread.setPriority(10);
        thread1.start();
        thread.start();
    }
}

class Ticket implements Runnable {
    private int ticketNum = 10;
    private boolean flag = true;

    @Override
    public void run() {
        while (flag) {
            buyTicket();
        }
    }

    private synchronized void buyTicket() {
        if (ticketNum <= 0) {
            flag = false;
            return;
        }

        System.out.println(Thread.currentThread().getName() + "购买第" + ticketNum + "票!");
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        ticketNum--;
    }
}
image.png

样例二:加入synchronized块自定义上锁对象

package com.example.demo.thread;

/**
 * @projectName: demo
 * @package: com.example.demo.thread
 * @className: UnsafeBank
 * @author:
 * @description: 多个提款机取票,观察最终的账户余额和到手金额
 * @date: 2021/12/8 10:33
 */
public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account("工资卡", 100);
        CashMachine cashMachine1 = new CashMachine(account, 100);
        CashMachine cashMachine = new CashMachine(account, 50);
        new Thread(cashMachine, "张三").start();
        new Thread(cashMachine1, "张三老婆").start();
    }
}


class Account {
    // 卡明
    private String name;
    // 卡内余额
    private int money;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

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

class CashMachine implements Runnable {
    private Account account;

    // 共计取出的金额
    private int nowMoney;

    // 提款机中取出的金额
    private int getMoney;


    public CashMachine(Account account, int getMoney) {
        this.account = account;
        this.getMoney = getMoney;
    }

    @Override
    public void run() {
        synchronized (account){
            if (this.account.getMoney() - getMoney < 0) {
                System.out.println(Thread.currentThread().getName() + "卡里余额不足!");
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.draw();
        }
    }

    private void draw() {
        // 卡内余额
        int temp = this.account.getMoney() - getMoney;
        this.account.setMoney(temp);
        // 手里
        this.nowMoney = this.nowMoney + getMoney;
        System.out.println(Thread.currentThread().getName() + "取出" + getMoney + "元,账户余额" + temp + "元,共计到手" + this.nowMoney + "元");
    }
}
金额不会冒出

你可能感兴趣的:(8.2、线程同步(不安全样例改良))