多线程同步机制2-深入理解synchronized关键字
来源:互联网 发布:java线程池下载多任务 编辑:程序博客网 时间:2024/05/21 11:19
上一节讲了关键字synchronized的基本用法。这一节我将用一个实际的例子来深入多线程同步机制的理解。
存取款改造
/** * Created by qianyi on 2017/9/9. */public class FetchOperationMoney { public static void main(String[] args) { Bank bank = new Bank(); Thread t1 = new AtmSaveMoney(bank);//ATM存钱 Thread t2 = new GuitaiSaveMoney(bank);//柜台存钱 Thread t3 = new AtmFetchMoney(bank);//ATM取钱 Thread t4 = new GuiTaiFetchMoney(bank);//柜台取钱 //分别启动四个线程去对账户进行操作 bank.searchBalance();//访问没有加synchronized的方法, t1.start(); bank.searchBalance();//访问没有加synchronized的方法, t2.start(); bank.searchBalance();//访问没有加synchronized的方法, t3.start(); bank.searchBalance();//访问没有加synchronized的方法, t4.start(); bank.searchBalance();//访问没有加synchronized的方法, }}/** * 银行账户 */class Bank { /** * 账户余额 */ private int balance = 1000; /** * 操作取钱的方法 * * @param number 取钱金额 * @return */ public synchronized int fetchMoney(int number, String channel) { System.out.println("取款开始:"); System.out.println("取款来自渠道:" + channel + ",账户操作前余额:" + balance); System.out.println("账户取款金额:" + number); if (number < 0) { return -1; } else if (number > balance) { return -2; } else if (balance < 0) { return -3; } else { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } balance -= number; System.out.println("balance is:" + balance); System.out.println("------------------------------------------------"); return number; } } /** * 存钱 * * @param number 存钱金额 * @return */ public synchronized int saveMoney(int number, String channel) { System.out.println("存款开始:"); System.out.println("存款款来自渠道:" + channel + ",账户操作前余额:" + balance); System.out.println("账户存款金额:" + number); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } balance += number; System.out.println("balance is:" + balance); System.out.println("------------------------------------------------"); return number; } /** * 查询余额,没有关键字synchronized */ public void searchBalance() { System.out.println("*****************************************"); System.out.println("查询----账户余额为:" + balance); System.out.println("*****************************************"); }}/** * ATM取钱 */class AtmFetchMoney extends Thread { private Bank bank; public AtmFetchMoney(Bank bank) { this.bank = bank; } @Override public void run() { bank.fetchMoney(800, "ATM"); }}/** * 柜台取钱 */class GuiTaiFetchMoney extends Thread { private Bank bank; public GuiTaiFetchMoney(Bank bank) { this.bank = bank; } @Override public void run() { bank.fetchMoney(800, "柜台"); }}/** * 柜台存钱 */class GuitaiSaveMoney extends Thread { private Bank bank; public GuitaiSaveMoney(Bank bank) { this.bank = bank; } @Override public void run() { bank.saveMoney(800, "柜台"); }}/** * ATM存钱 */class AtmSaveMoney extends Thread { private Bank bank; public AtmSaveMoney(Bank bank) { this.bank = bank; } @Override public void run() { bank.saveMoney(800, "ATM"); }}
首先上面代码:
1.账户初始化余额1000
2.Bank有两个方法,分别是取钱和存钱的操作,取钱和存钱的操作分别传入了金额和渠道(ATM 柜台),都使用了synchronized关键字。
3.四个多线程。ATM取钱、ATM存钱、柜台存钱、柜台取钱,对其存钱和取钱的操作。
4.增加一个查询余额searchBalance()的方法,查询余额,没有关键字synchronized.
5. 模拟存钱需要等待10S,即 Thread.sleep(10000);
6.main方法中,我们多次调用查询余额方法,然后启动多个线程去操作同一个账户。分别通过ATM和柜台去存800和取款800。
如果余额依然是1000,那么说明多线程同步机制起到了实质的作用。
结果:
*****************************************查询----账户余额为:1000**********************************************************************************查询----账户余额为:1000*****************************************存款开始:*****************************************查询----账户余额为:1000*****************************************存款款来自渠道:ATM,账户操作前余额:1000账户存款金额:800*****************************************查询----账户余额为:1000**********************************************************************************查询----账户余额为:1000*****************************************balance is:1800------------------------------------------------取款开始:取款来自渠道:柜台,账户操作前余额:1800账户取款金额:800balance is:1000------------------------------------------------取款开始:取款来自渠道:ATM,账户操作前余额:1000账户取款金额:800balance is:200------------------------------------------------存款开始:存款款来自渠道:柜台,账户操作前余额:200账户存款金额:800balance is:1000------------------------------------------------
总结如下:
通过上面的例子可以发现,没有加synchronized关键字的方法searchBalance()不受同步机制的影响。其余的方法存款取款依次操作。不会出现竞争统一资源导致数据不对。只有当第一个线程将对象锁释放之后,后面才有执行。
上面代码可以直接copy到本地执行
阅读全文
0 0
- 多线程同步机制2-深入理解synchronized关键字
- Java同步关键字Synchronized深入理解
- 深入理解synchronized关键字
- Java线程同步机制synchronized关键字的理解
- Java线程同步机制synchronized关键字的理解
- java的线程同步机制synchronized关键字的理解
- java的线程同步机制synchronized关键字的理解
- java的线程同步机制synchronized关键字的理解
- java的线程同步机制synchronized关键字的理解
- java的线程同步机制synchronized关键字的理解
- Java多线程同步 synchronized关键字
- android 多线程同步-synchronized关键字
- Java 多线程:synchronized 多线程同步关键字
- Java 多线程:synchronized 多线程同步关键字
- 深入理解Android多线程、线程同步及AsyncTask机制
- Java多线程:线程同步与关键字synchronized
- 43、多线程同步及synchronized关键字
- 43、多线程同步及synchronized关键字
- springboot xml简单实例
- 软件测试概念及分类整理汇总
- Django 开发学习笔记(3)- 编写自定义的页面
- 测试系列-CMMI 知识扫盲篇
- 算法练习(3):Median of Two Sorted Arrays
- 多线程同步机制2-深入理解synchronized关键字
- 京东笔试题 神奇数
- springboot mail简单实例
- 通过实例理解:C语言 volatile 关键字
- 网页退出弹出新网页或者收藏夹
- 9.9 7日知识实践和总结(关于JavaScript的数组操作)
- Django 开发学习笔记(4)- 关于数据 ORM
- 自己写的顺序表的基本操作,插入、删除、修改,给出完整代码,其中运用到goto语句
- IE9- 图片|遮挡|绝对|定位|元素的|解决|办法