VIP免费

java多线程学习笔记_线程的同步

精品 多线程同步synchronized 原创
26
DEMO程序园
程序猿 2020-07-02
积分:0

简介:

本文主要通过模拟取钱的流程来记录对多线程下共用变量的值的处理;假设张三和李四两兄弟取银行取统一账户下的钱,一个人拿着银行卡在自动取款机取钱,一个拿着存折在柜台取钱,账户上有10000元,假设两人都想取6000元。

file

由于我们没有使用同步关键字加锁,所以会出现两个人同时能取2000的情况,这种情况显然是不允许的。

解决方法就是通过加synchronized关键字锁住对象类就可以了;接下来我们就通过代码来模拟:

 

假设业务场景如下:

张三和李四两兄弟取银行取统一账户下的钱,一个人拿着银行卡在自动取款机取钱,一个拿着存折在柜台取钱,账户上有10000元,假设两人都想取6000元。

 

代码实现:

新建一个账户类Account.java

package com.democxy.thread;
import java.util.Date;
/**
 * 定义账户
 * @author democxy
 *
 */
public class Account {
    //定义账户余额
    public static double money = 10000;
    
    /**
       *    取钱方法
     * @param outMoney 要取的钱
     * synchronized 关键字,锁住Account对象,直到当前执行withOutMoney方法的线程执行完毕后才释放对象,其他线程才可用
     */
    public synchronized void withOutMoney(double outMoney) {
        //获取线程名字
        String name = Thread.currentThread().getName();
        System.out.println(new Date().toLocaleString()+name+"本次取钱:"+outMoney+"元");
        if (outMoney<money) {
            money = money-outMoney;
            System.out.println(new Date().toLocaleString()+name+"取钱结束...........账户还剩"+money+"元");
        }else {
            System.out.println(new Date().toLocaleString()+name+"取钱失败,原因:余额不足,当前只有"+money+"元");
            System.out.println("--------------------------");
            System.out.println("--------------------------");
            System.out.println("--------------------------");
        }
        
        
    }
}

 

 

新建一个线程类User .java

package com.democxy.thread;
import java.util.Date;
public class User implements Runnable {
    
    //定义账户
    Account account;
    //定义取钱金额
    double outMoney;
    public User(Account account, double outMoney) {
        this.account = account;
        this.outMoney = outMoney;
    }
    @Override
    public void run() {
        try {
            //让线程休息1秒,模拟输入密码的过程
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        //获取线程名字
        String name = Thread.currentThread().getName();
        System.out.println(new Date().toLocaleString()+name+"输完密码,账户当前余额:"+account.money+"元,开始取钱............");
        //执行取钱的方法
        account.withOutMoney(outMoney);
        
    }
}

 

 

新建一个执行类

package com.democxy.thread;
/**
 * 多线程demo
 * @author democxy
 *
 */
public class ThreadDemo {
    public static void main(String[] args) {
        Account account = new Account();
        
        double outMoney = 6000;
        
        User user = new User(account, outMoney);
        
        Thread thread1 = new Thread(user,"张三");
        
        
        Thread thread2 = new Thread(user,"李四");
        
        thread1.start();
        
        thread2.start();
    }
}

 执行结果1:

执行结果2:



评论
最新发布
2024-03-31
2024-03-31
2024-03-28
2024-03-28
2024-03-25
2024-03-19
2024-03-19
2024-03-13
2024-03-13
2024-03-12
layui

微信扫码关注DEMO程序园公众号

本周热门
1587
1274
1076
997
898
850
840
729
639
424
热门下载
27
20
19
14
14
12
12
12
12
11