zoukankan      html  css  js  c++  java
  • 多线程同步机制练习之银行存钱

      1 package day2_4;
      2 
      3 import java.util.concurrent.locks.ReentrantLock;
      4 
      5 /**
      6  * 银行有一个账户。
      7  * 两个储户向同一个账户里存钱,每个储户都是存3000元,分三次,每次存1000。
      8  * 每次存完打印账户余额
      9  *
     10  * 分析:
     11  * 1.是多线程问题吗?  是,两个储户线程
     12  * 2.是否有共享数据?  有,同一个账户(或账户余额)
     13  * 3.是否有线程安全问题? 有
     14  * 4.如何解决线程安全问题? 同步机制:有三种方式
     15  *
     16  *
     17  * @Author Tianhao
     18  * @create 2021-02-05-18:21
     19  */
     20 public class AccountTest {
     21     public static void main(String[] args) {
     22         Account acct = new Account(0);
     23         Customer c1 = new Customer(acct);
     24         Customer c2 = new Customer(acct);
     25         c1.setName("客户1");
     26         c2.setName("客户2");
     27         c1.start();
     28         c2.start();
     29     }
     30 
     31 }
     32 
     33 //账号
     34 class Account {
     35     //余额
     36     private double balance = 0;
     37 
     38     public Account(double balance) {
     39         this.balance = balance;
     40     }
     41 
     42     private ReentrantLock lock = new ReentrantLock();
     43 
     44     //存钱操作
     45     //这里虽然线程类是继承Thread方式创建,但同步方法上没有static修饰
     46     //因为这个方法所在Account类的对象acct是多个线程共享的,就可以用this作为同步监视器
     47     //解决线程安全问题:方式一:使用同步方法
     48 //    public synchronized void deposit(double amt) {
     49 //        if (amt > 0) {
     50 //            balance += amt;
     51 //            try {
     52 //                Thread.sleep(1000);
     53 //            } catch (InterruptedException e) {
     54 //                e.printStackTrace();
     55 //            }
     56 //            System.out.println( Thread.currentThread().getName() + ":存钱成功。余额:" + balance);
     57 //        }
     58 //    }
     59 
     60     //解决线程安全问题:方式二:使用同步代码块
     61     public void deposit(double amt) {
     62         synchronized (this) {
     63             if (amt > 0) {
     64                 balance += amt;
     65                 try {
     66                     Thread.sleep(1000);
     67                 } catch (InterruptedException e) {
     68                     e.printStackTrace();
     69                 }
     70                 System.out.println(Thread.currentThread().getName() + ":存钱成功。余额:" + balance);
     71             }
     72         }
     73     }
     74 
     75 
     76     //解决线程安全问题:方式三:使用lock方法
     77 //    public synchronized void deposit(double amt) {
     78 //        try {
     79 //            lock.lock();
     80 //            if (amt > 0) {
     81 //                balance += amt;
     82 //                try {
     83 //                    Thread.sleep(1000);
     84 //                } catch (InterruptedException e) {
     85 //                    e.printStackTrace();
     86 //                }
     87 //                System.out.println( Thread.currentThread().getName() + ":存钱成功。余额:" + balance);
     88 //            }
     89 //        }finally {
     90 //            lock.unlock();
     91 //        }
     92 //    }
     93 
     94     public double getBalance() {
     95         return balance;
     96     }
     97 }
     98 //储户
     99 class Customer extends Thread{
    100     private Account acct;
    101     //将Account对象作为参数传入到构造器,这样就保证了创建的
    102     // 每个Customer对象都是同一个Account对象
    103     public Customer(Account acct) {
    104         this.acct = acct;
    105     }
    106 
    107     @Override
    108     public void run() {
    109         for (int i = 0; i < 3; i++) {
    110             acct.deposit(1000);
    111         }
    112     }
    113 }
  • 相关阅读:
    float转varchar
    我的优化经验:内链是SEO的基础
    转:2008年微软Windows硬件工程(WinHEC)大会
    sql语句去掉前面的0(前导零,零前缀)
    去掉ID重复的数据
    蛙蛙推荐:蛙蛙牌firefox插件
    每日阅读20081127
    网赚经验之谈:成为高手之路
    (chinaz)巧妙选购付费链接
    把某个表的数据导出成insert语句(数据导出 insert语句)
  • 原文地址:https://www.cnblogs.com/zui-ai-java/p/14379461.html
Copyright © 2011-2022 走看看