• 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏吧

多线程练习一:银行有一个账户,有两个储户分别向同一个账户存3000元,每次存1000,存三次,每次存完打印账户余额(两个储户尽量交替存)

互联网 diligentman 4周前 (01-31) 10次浏览

多线程练习一:银行有一个账户,有两个储户分别向同一个账户存3000元,每次存1000,存三次,每次存完打印账户余额(两个储户交替存)

​ 对于本题,需要有账户(Account)、储户(User)、以及一个测试类(AccountTset)

​ 可以分别用继承Thread类和实现Runnable接口的方式来解决,同时需要注意线程同步的安全问题。

​ 说明:用户User需要共享一个账户Account,这时需要在User类中添加一个Account类型的属性,以及为User类提供Account有参构造,以调用其存钱方法,同时在测试类中也可保证不管new 多少个User都是共享同一个Account。

1.继承Thread类的方法:

class Account {
    //账户余额为money
    private double money;
	//有参构造器
    public Account(double money) {
        this.money = money;
    }
	//存钱方法
    public void cunqian(double jine) {
        if (jine > 0) {
          	//用同步代码块的方式解决线程安全问题,同步监视器为Account.class
            synchronized (Account.class) {
            	Account.class.notify();
                money += 1000;
              
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
              
                System.out.println(Thread.currentThread().getName() + "-存款,账户余额为:" + money);
                //
                try {
                    Account.class.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

class User extends Thread {
    private Account account;
	//有参构造器
    public User(Account account) {
        this.account = account;
    }
    //重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            account.cunqian(1000);
        }
    }
}


public class AccountTest {
    public static void main(String[] args) {
        Account acc = new Account(0);
		//创建两个User对象 (两个线程)
        User u1 = new User(acc);
        User u2 = new User(acc);
		//为两个对象(线程)命名
        u1.setName("甲");
        u2.setName("乙");

        u1.start();
        u2.start();
    }
}

2.实现Runnable接口:

​ 说明: ReentrantLock lock = new ReentrantLock(true);在公平锁(参数为true)中,线程执行完会让出cpu执行权给下一个排队的线程。而非公平锁(参数为false或五参数)对锁的获取是乱序的。

class Account {
    private double money;
	实例化ReentrantLock,公平锁
    ReentrantLock lock = new ReentrantLock(true);

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

    public void cunqian(double jine) {
        if (jine > 0) {
            lock.lock();
            money += jine;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "-存款,账户余额为:" + money);
        }
        lock.unlock();
    }
}


class User implements Runnable {
    private Account account;

    public User(Account account) {
        this.account = account;
    }

    @Override
    public void run() {
        for (int i = 0; i < 3; i++) {
            account.cunqian(1000);
        }
    }
}

public class AccountTest {
    public static void main(String[] args) {
        Account acc = new Account(0);
        User user = new User(acc);

        Thread t1 = new Thread(user);
        Thread t2 = new Thread(user);

        t1.setName("甲");
        t2.setName("乙");

        t1.start();
        t2.start();
    }
}

赵大海看完能不能发把ju?


喜欢 (0)