Java多线程练习一:银行有一个账户,有两个储户分别向同一个账户存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?