多线程系列二——java线程间的互斥与同步
来源:互联网 发布:淘宝发安能物流好恶心 编辑:程序博客网 时间:2024/05/01 13:09
“线程互斥是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。”
我们可以用银行转账的例子加以说明:
1、甲乙两用户对银行同一账户进行操作,余额为1000元;
2、甲用户将银行余额1000元读取到本地,进行取款操作。在进行取款过程中,乙用户向银行账户进行存款300元操作并将账户余额更新,而此时甲用户进行取款是建立在原始1000元的基础上进行的。完成操作后将最终错误的800元余额更新至银行账户。。。
用程序模拟此示例:
public class TestTransferAccounts {//存取银行账户余额static int balance = 1000;//main方法中模拟两个用户同时对该银行账户进行更新(其中一个进行取款操作,另一个对账户进行汇款操作)public static void main(String[] args) {new TestTransferAccounts().test();}public void test(){BankOperator bankOperator= new BankOperator();new Thread(new Runnable() {@Overridepublic void run() {bankOperator.addAccounts();}}).start();new Thread(new Runnable() {@Overridepublic void run() {bankOperator.reduceAccounts();}}).start();//主线程等到另外两个线程操作完成后,查询账户余额进行打印。try {Thread.sleep(1000);System.out.println("查询账户余额:" + balance);} catch (InterruptedException e) {e.printStackTrace();}}class BankOperator{//汇款操作方法public void addAccounts(){//将余额读取到本地int myBalance = balance;//中间处理过程花费500ms。。。try {Thread.sleep(200);myBalance += 300;} catch (InterruptedException e) {e.printStackTrace();}//将余额更新回账目balance = myBalance;System.out.println(Thread.currentThread().getName() + ":" + balance);}//取款操作方法public void reduceAccounts(){//将余额读取到本地int myBalance = balance;//中间处理过程花费200ms。。。try {Thread.sleep(500);myBalance -= 200;} catch (InterruptedException e) {e.printStackTrace();}//将余额更新回账目balance = myBalance;System.out.println(Thread.currentThread().getName() + ":" + balance);}}}
执行结果:
正如文章开头我们提到的线程互斥概念,我们需要对汇款、取款两个线程添加互斥机制,同时只能允许一个用户调用addAccounts或reduceAccounts方法,我们需要对BankOperator对象内的这两个方法添加同步的机制,防止银行将我们的账户余额搞乱。
public class TestTransferAccounts {//存取银行账户余额static int balance = 1000;//main方法中模拟两个用户同时对该银行账户进行更新(其中一个进行取款操作,另一个对账户进行汇款操作)public static void main(String[] args) {new TestTransferAccounts().test();}public void test(){BankOperator bankOperator= new BankOperator();new Thread(new Runnable() {@Overridepublic void run() {bankOperator.addAccounts();}}).start();new Thread(new Runnable() {@Overridepublic void run() {bankOperator.reduceAccounts();}}).start();//主线程等到另外两个线程操作完成后,查询账户余额进行打印。try {Thread.sleep(1000);System.out.println("查询账户余额:" + balance);} catch (InterruptedException e) {e.printStackTrace();}}class BankOperator{//亏款操作方法public void addAccounts(){synchronized (this) {//将余额读取到本地int myBalance = balance;//中间处理过程花费500ms。。。try {Thread.sleep(500);myBalance += 300;} catch (InterruptedException e) {e.printStackTrace();}//将余额更新回账目balance = myBalance;System.out.println(Thread.currentThread().getName() + ":" + balance);}}//取款操作方法public void reduceAccounts(){synchronized (this) {//将余额读取到本地int myBalance = balance;//中间处理过程花费200ms。。。try {Thread.sleep(500);myBalance -= 200;} catch (InterruptedException e) {e.printStackTrace();}//将余额更新回账目balance = myBalance;System.out.println(Thread.currentThread().getName() + ":" + balance);}}}}
执行结果:
synchronized关键字已经帮我们实现了同步的效果,而jdk5.0为我们提供了Lock对象,来实现更为强大的同步效果。
有关synchronized与Lock的比较可以参看:
http://www.cnblogs.com/benshan/p/3551987.html#top
0 0
- 多线程系列二——java线程间的互斥与同步
- 多线程编程—线程的同步与互斥
- java基础——多线程(线程的同步互斥与通信)
- java基础——多线程(线程的同步互斥与通信)
- 多线程篇(二)——线程之间的同步与互斥,关键段的使用
- java线程系列---关于线程同步与互斥问题
- java多线程(二)线程的互斥
- java多线程总结笔记4——线程互斥与同步
- JAVA线程的同步与互斥
- Linux下的多线程编程二(线程的同步与互斥)
- java多线程Thread线程同步与互斥、锁机制
- Linux多线程编程(二)---线程之间的同步与互斥
- Linux多线程编程(二)---线程之间的同步与互斥
- Linux — 浅析线程以及多线程的同步与互斥
- Java多线程间的同步互斥
- 线程间的同步与互斥
- Java多线程技术篇--线程的互斥与同步通信
- java线程深度解析(二)——线程互斥技术与线程间通信
- JAVA 运算符和条件结构
- Spring MVC 实现增删改查
- 项目24.4个人所得税计算器if语句版
- iperf 2.0.5的bug
- 51单片机之闹钟制作
- 多线程系列二——java线程间的互斥与同步
- PreferenceActivity
- SSH搭建web java
- 黑马程序员——5.多线程
- Valid Parentheses
- 拓扑排序
- 51单片机之蓝牙控制风扇
- 观后感
- String StringBuilder StringBuffer 对比总结