线程 wait() sychronized() notifyAll() 实例应用

三个模型类:


帐号类:主要是帐号资金的增加和减少操作,需要sychronized关键字保证线程安全

package thread;

/**
 * create by frank
 * on 2018/04/20
 */
public class Customer{

    private int money;

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

    public int getMoney() {
        return money;
    }

    public synchronized void add(int money) {
        this.money += money;
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public synchronized int out(int money) {
        int rst = 1;
        if (this.money >= money){
            this.money -= money;
        }else rst = 2;

        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return rst;
    }


}


公司类:公司类功能主要为员工发放工资,调用帐号类的out方法进行工资发放,当帐号内资金少于工资时,公司类进行wait()操作,等到银行类进行资金填充,此期间有以下两个操作

1、释放执行权,其他线程可以进行执行

2、释放对象锁  也就是代码中sychronised() 关键字括号中的customer 对象


package thread;
/**
 * create by frank
 * on 2018/04/20
 */
public class Bank implements Runnable{
    private Customer customer;
    private String name;
    public Bank(Customer customer){
        this.customer = customer;
    }

    public String getName() {
        return name;
    }


    @Override
    public void run() {
        //对象锁
        synchronized (customer){
            //获取对象锁和执行权
            if(customer.getMoney() < 1000){
                customer.add(2000);
                System.out.println("银行利息到账,余额为:"+customer.getMoney());
                //通知Company结束等待
                customer.notifyAll();
            }
        }



    }
}


银行类:银行类在公司类资金充裕时不进行帐号资金操作,当公司类进入等待资金填充状态时,银行类进行资金添加,主要调用帐号的add方法进行资金充值,充值完成后进行notifyAll();使得等待资金注入的公司类正常的进行下一步操作。

package thread;
/**
 * create by frank
 * on 2018/04/20
 */
public class Bank implements Runnable{
    private Customer customer;
    private String name;
    public Bank(Customer customer){
        this.customer = customer;
    }

    public String getName() {
        return name;
    }


    @Override
    public void run() {
        //对象锁
        synchronized (customer){
            //获取对象锁和执行权
            if(customer.getMoney() < 1000){
                customer.add(2000);
                System.out.println("银行利息到账,余额为:"+customer.getMoney());
                //通知Company结束等待
                customer.notifyAll();
            }
        }



    }
}

测试类:


package thread;
/**
 * create by frank
 * on 2018/04/20
 */
public class Test {

    public static void main(String[] args) {
        Customer customer = new Customer();
        customer.setMoney(3000);
        Bank bank = new Bank(customer);

        Company company = new Company(customer);
        for (int i = 0; i < 10; i++) {

            company.run();

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

            bank.run();

        }


    }
}

运行结果:

公司帐号发放工资,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000
公司帐号发放工资,余额为:1000
公司帐号发放工资,余额为:0
银行利息到账,余额为:2000

公司帐号发放工资,余额为:1000


sleep()、wait()

sleep:释放执行权,但是不是放对象锁

wait:释放执行权和对象锁


notify()、notifyAll();

notify():通知当前等待线程  多线程情况下,可能会因为线程优先级,线程争夺等原因导致结果不同

notifyAll():通知所有等待线程

猜你喜欢

转载自blog.csdn.net/JasonHector/article/details/80016459