线程同步:
一、线程同步:
线程的同步,就是要保证线程在执行某个计算时,需要保证相关的数据在这个计算过程中只能被一个线程访问,即保证访问数据的原子性---就像一个坐位,只能同时被一个人(线程)所使用。
二、举例,以在银行取钱为例子:
1.创建账户:
package 线程同步; /** * 银行账户对象 * @author Administrator * */ public class Account { private int total=0; //构造有指定金额的银行账户 public Account(int save){ this.total = save; } public String toString(){ return "账户余额:"+total; } //取钱的 private void disSave(int count){ try{ Thread.sleep(1000); }catch(Exception ed){ } total=total-count; } //从账户上提取现金的调用方法 public int getCash(int count){ //金额不足 if (total<count) { return -1; } //从账户上减去提取金额 disSave(count); return count; } }
2.取钱线程:
package 线程同步; public class GetCashThread extends Thread { private Account ac;//操作账户 private String flag;//取钱方式 private int disCount;//取现金额 @Override public void run() { // TODO Auto-generated method stub //super.run(); //在这里取钱 //synchronized (ac) { int cash=ac.getCash(disCount); System.out.println(flag+"取了:"+cash); //} } public GetCashThread(Account ac,String flag,int disCount){ this.ac = ac; this.flag = flag; this.disCount = disCount; } }
3.Main类:
package 线程同步; public class DriverBank { public static void main(String[] args) { //创建一个账号: Account ac = new Account(5000); //从ATM取 GetCashThread atmGet = new GetCashThread(ac, "ATM取款", 2500); //从柜台取 GetCashThread counterGet = new GetCashThread(ac, "从柜台取款", 2600); //启动取款线程 atmGet.start(); counterGet.start(); //主线程暂停,等到前面两个取款线程完成,打印出账户余额 try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(ac); } }
三、运行结果:
账户共有5000,可是分别取到2500,2600,余额是-100,这就是线程不同步,所造成的结果.ATM的线程取钱时,柜台取钱进入取钱,此时的ATM的线程还未结算完,导致账户上还是5000,
四、处理
解决原理:避免多个线程同时操作某一个对象的数据,就要让多线程操作对象的数据时候有一个先后顺序,一个操作完成另一个线程在操作的。
解决1---使用synchronized关键字
这个关键字可以放在一个方法前,表示这个方法同时只能被一个线程访问,或通过锁定某个对象放在代码块前,表示其限定的代码块只能同时被一个线程防问。
代码改善:
synchronized (ac) { int cash=ac.getCash(disCount); System.out.println(flag+"取了:"+cash); }
运行结果:
解决2--使用java.util.concurrent包
这个包中有许多对并发编程有良好支持的类,其中新增了一个java.util.concurrent.locks.Lock接口,这是一个“锁”对象的接口,它的多个实现的子类可用来支持线程同步时灵活的锁机制
代码改善:
package 线程同步;
import java.util.concurrent.locks.*; import java.util.concurrent.locks.ReentrantLock; public class GetCashThread extends Thread { private Account ac;//操作账户 private String flag;//取钱方式 private int disCount;//取现金额 //定义一个同步锁 private static Lock myLock = new ReentrantLock(); @Override public void run() { // TODO Auto-generated method stub //super.run(); //在这里取钱 try{ myLock.lock();// 仅有一个线程可同时执行此段代码 int cash=ac.getCash(disCount); System.out.println(flag+"取了:"+cash); }finally{ myLock.unlock(); } } public GetCashThread(Account ac,String flag,int disCount){ this.ac = ac; this.flag = flag; this.disCount = disCount; } }
运行结果:
五、总结.
避免多线程同时操作某一对象的数据,要给线程加上执行顺序.
相关推荐
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例1: 银行存款 5000。柜台,折:取3000;提款机,卡:取 3000。剩余:2000 举例2...
C#线程同步的几种方法 C#线程同步的几种方法
.NET多线程同步方法详解(一):自由锁(InterLocked) 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,...
1.使用三种VC的多线程同步方法编写一个多线程的程序(要求在屏幕上先显示Hello,再显示World)。 1)基于全局变量的多线程同步程序; 2)基于事件的多线程同步程序; 3)基于临界区的多线程同步程序。
MFC 多线程及线程同步 MFC 多线程及线程同步 MFC 多线程及线程同步
java线程同步java线程同步java线程同步
简单学习用例,利用线程锁对线程同步进行控制,保证对公共资源的访问不出现错误!
本文件为操作系统中的线程同步实验的实验报告,有详细的代码和解释。
线程同步的四种方法的代码。事件 互斥量 信号量 临界区
多线程中的同步问题的几种解决方案,新手可以看看。主要通过临界区线程同步,互斥内核对象、事件内核对象,信号量内核对象来实现线程同步问题。
介绍了linux线程同步的所有方式,包括互斥、自旋、信号量、条件变量等技术
操作系统实验 多线程同步与互斥 java编写 可动态创建
通过模拟公交车运行时,司机,售票员以及乘客之间的同步状态来实现线程同步
很不错的Delphi多线程和线程同步的例子,完整源码 原来的一个不知道CSDN怎么把文件搞丢了!新传一个资源,包含一个线程排序的例子!代码均搜集自网上!
C#_线程同步lock,Monitor,Mutex,同步 互斥 监控 锁
简单实现多线程同步示例(模拟购票系统),内容为实现多线程同步过程,模拟购票系统进行同步购买情况;该处并未考虑线程守护问题,后期将对线程锁等安全问题进行初步研究!
C#线程同步,多个线程去执行,检测到最后一个线程执行完成,主线程继续执行其他业务AutoResetEvent
本工程中包含了线程同步的五种方法,现在拿出来和大家一起分享,VC6.0编译测试通过,工程中包含了5个小工程,具体讲述每种线程同步方法的具体使用列子,而且有详细的注释。
线程同步技术剖析!! 自己看了还不错!需要的下吧
多线程同步解决卖票问题