银行有一个账户。 有两个储户分别向同一个账户存3000元,每次存1000,存3次。每次存完打印账户余额。
问题:该程序是否有安全问题,如果有,如何解决?
【提示】 1,明确哪些代码是多线程运行代码,须写入run()方法 2,明确什么是共享数据。 3,明确多线程运行代码中哪些语句是操作共享数据的。
【拓展问题】可否实现两个储户交替存钱的操作
1.静态方法实现:
/** * @author 欧玉成 * @version 1.0 * 2024/7/21 */ public class AccountThreadPractice { public static void main(String[] args) { AccountThread m1=new AccountThread(); AccountThread m2=new AccountThread(); m1.setName("小王"); m2.setName("小李"); m1.start(); m2.start(); } } //实现1 class AccountThread extends Thread{ //共享资源区 private static int account; @Override public void run(){ for(int i=0;i<3;i++){ addAcoount(); } } public static synchronized void addAcoount(){ account+=1000; System.out.println(Thread.currentThread().getName() + "存入1000元" ); System.out.println("当前账户存储为:"+account); } }
结果:
2.非静态方法实现:
package atguigu.threadtest.practice; /** * @author 欧玉成 * @version 1.0 * 2024/7/21 */ public class AccountThreadPractice2 { public static void main(String[] args) { AccountRunnable ar=new AccountRunnable(); Thread m1=new Thread(ar,"小李"); Thread m2=new Thread(ar,"小王"); m1.start(); m2.start(); } } class AccountRunnable implements Runnable{ //共享资源区 private static int account; //个人的钱 @Override public void run(){ for(int i=0;i<3;i++){ addAcoount(); } } public synchronized void addAcoount(){ account+=1000; System.out.println(Thread.currentThread().getName() + "存入1000元" ); System.out.println("当前账户存储为:"+account); } }
3.同步代码块实现:(也可以用匿名内部类上锁资源)
package atguigu.threadtest.practice; /** * @author 欧玉成 * @version 1.0 * 2024/7/21 */ public class AccountThreadPractice3 { public static void main(String[] args) { Account account=new Account(); Customer c1=new Customer(account,"小王"); Customer c2=new Customer(account,"小李"); c1.start(); c2.start(); } } class Account{ private int account=0; public int getAccount() { return account; } public void addAccount(int m){ account+=m; } public synchronized void addAcoount(){ addAccount(1000); System.out.println(Thread.currentThread().getName() + "存入1000元" ); System.out.println("当前账户存储为:"+getAccount()); } } class Customer extends Thread{ private Account account; Customer(){ } Customer(Account account,String name){ super(name); this.account=account; } @Override public void run(){ for(int i=0;i<3;i++){ account.addAcoount(); } } }
//(也可以用匿名内部类上锁资源)
package atguigu.threadtest.practice; /** * @author 欧玉成 * @version 1.0 * 2024/7/21 */ public class AccountThreadPractice3 { public static void main(String[] args) { Account account=new Account(); Thread c1 = new Thread("小李") { public void run() { for(int i=0;i<3;i++){ synchronized (account) { account.addAcoount(); } } } }; Thread c2 = new Thread("小王") { public void run() { for(int i=0;i<3;i++){ synchronized (account) { account.addAcoount(); } } } }; c1.start(); c2.start(); } } class Account{ private int account=0; public int getAccount() { return account; } public void addAccount(int m){ account+=m; } public void addAcoount(){ addAccount(1000); System.out.println(Thread.currentThread().getName() + "存入1000元" ); System.out.println("当前账户存储为:"+getAccount()); } }
实现两个储户交替存钱的操作:尝试用notify()和wait()匿名内部类实现,但失败...