Java-锁练习

银行有一个账户。 有两个储户分别向同一个账户存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()匿名内部类实现,但失败...

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值