1、线程是什么,线程是一份独立运行的程序,有自己专用的运行空间,有可能和其他线程共享一些资源,比如,内存,文件,数据库等。
2、线程同步的概念。当多个线程共同占用一个资源的时候,这时候就要用到线程同步这个概念。线程同步的“同”字可能会让很多人误解,往往会被理解成几个线程一起进行,其实“同”的真正解释是指协同、协助、互相配合。比如说厕所,一个厕所同时只能给一个人占用,当一个人进去的时候,其他人就要在外面等待,里面的人出来以后外面的人才能够进去使用。 再来说说为什么需要线程同步, 最好的例子就是银行的账户,假设你在银行开了一个账户,Account,同时拿到一本存折还有一张银行卡,假设你的银行卡里面有3000大洋。有一天,你和你的女朋友分别拿着银行卡和存折同时在ATM取款机还有银行柜台取钱。两种方式两个线程,共享Account这个账户,假使你用银行卡取钱的时候线程1在操作Account,取出3000,但是在ATM吐出钱而Account还没有扣钱的时候,线程2又启动了,因为线程2并不知道线程1已经取了3000,你的女朋友在柜台又取了3000,这样银行岂不是亏了3000?
public getCash(Account ac, String name, int cash) { this.ac = ac; this.cash = cash; this.name = name; } public void run() { // synchronized (ac) { int count = ac.getCash(cash); System.out.println(name + "取了" + count); // } } public Account(int num){ this.total=num; } public int getCash(int cash){ if(cash>total){ return -1; } else{ disSave(cash); return cash; } } public static void main(String arg[]) throws Exception{ Account ac=new Account(3000); getCash thread1=new getCash(ac,"ATM",3000); getCash thread2=new getCash(ac,"柜台",3000); thread1.start(); thread2.start(); Thread.sleep(5000); System.out.println(ac); }
运行结果:柜台取了3000 ATM取了3000 总共还有金额:-3000
3、然后我们看一下怎么样才能实现线程的同步。
(1)关键字synchronized,我们可以在我们需要共享的资源上加锁,这样就可以保证该对象只能被一个用户使用。
a、synchronized 锁定一个独立的代码块
public void run(){
while(true){
synchronized(lock){
...... //共享资源
}
}
}
上诉代码可以理解为每当执行while里面代码时,共享资源就会被锁定,执行完以后释放锁。
b、synchronized 关键字还可以修饰一个函数
//取钱,够的话扣除然后返回要扣除的钱的总数不够的话返回-1
public synchronized int getCash(int cash){ if(cash>total){ return -1; } else{ disSave(cash); return cash; } }
同理当使用上面的函数的时候这个函数就会被锁定。
PS: 需要注意的就是synchronized(Lock)里面的Lock必须是公共锁。假如我在Thread1中创建了一个锁lock1,在Thread2也创建了一个锁lock2,那么“上锁”也就没意义了。就好像一个公共教室,我进门锁了门,但是另一个人开了后门从后门进,我锁没锁前门也就没有意义了。
2、看下述代码
private byte[] lock = new byte[0];
public void methodA() {
synchronized(lock) {
…
}
}
使用这种方式生成锁可以称作大神级别的作品,后来查找了下原因,因为生成零长度的byte[]对象只需3条操作码,而Object lock= new Object()则需要7行操作码,所以生成byte[0]是最经济的一种方式。
(2)使用同步锁Lock。Java中有一个包java.util.concurrrent.locks.Lock接口。 具体的使用方法是:
//先生成一个公共锁。
Java.util.concurrent.Lock lock=new java.util.concurrrent.locks.Lock.ReentrantLock();
lock.lock();
//开始上锁
try{
doSomeThing. //共享资源
}
finally{
lock.unlock();
}
synchronized和lock相同与不同: 凡是synchronized能实现的效果lock都是可以实现的,不同的是,lock锁定后执行的内容必须放在try里面,而解锁的unlock必须放finally里面。 当然,同步是要很大的系统开销作为代价的,有时候可能会导致死锁,因此要避免无谓的同步。
相关推荐
线程同步,指一个线程发出某一功能调用时,在没有得到结果之前,该调用不返回。同时其它线程为保证数据一致性,不能调用该功能。 举例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个小工程,具体讲述每种线程同步方法的具体使用列子,而且有详细的注释。
线程同步技术剖析!! 自己看了还不错!需要的下吧
多线程同步解决卖票问题