ImageVerifierCode 换一换
格式:DOCX , 页数:8 ,大小:17.94KB ,
资源ID:80171      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-80171.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(java并发的处理方式.docx)为本站会员(b****1)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

java并发的处理方式.docx

1、java并发的处理方式java并发的处理方式 1 什么是并发问题。多个进程或线程同时(或着说在同一段时间内)访问同一资源会产生并发问题。银行两操作员同时操作同一账户就是典型的例子。比如A、B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户减去 50元,A先提交,B后提交。 最后实际账户余额为1000-50=950元,但本该为 1000+100-50=1050。这就是典型的并发问题。如何解决?可以用锁。用法1public class Test public synchronized void print() .; 某线程执行print()方法,则该对象将

2、加锁。其它线程将无法执行该对象的所有synchronized块。用法2public class Test public void print() synchronized(this)/锁住本对象 .; 同用法1, 但更能体现synchronized用法的本质。用法3public class Test private String a = test; public void print() synchronized(a)/锁住a对象 .; public synchronized void t() .; /这个同步代码块不会因为print()而锁定. 执行print(),会给对象a加锁,注意不是给

3、Test的对象加锁,也就是说 Test对象的其它synchronized方法不会因为print()而被锁。同步代码块执行完,则释放对a的锁。为了锁住一个对象的代码块而不影响该对象其它 synchronized块的高性能写法:public class Test private byte lock = new byte0; public void print() synchronized(lock) .; public synchronized void t() .; 静态方法的锁public class Test public synchronized static void execute()

4、 .; 效果同public class Test public static void execute() synchronized(TestThread.class) .; 3 Java中的锁与排队上厕所。锁就是阻止其它进程或线程进行资源访问的一种方式,即锁住的资源不能被其它请求访问。在JAVA中,sychronized关键字用来对一个对象加锁。比如:public class MyStack int idx = 0; char data = new char6; public synchronized void push(char c) dataidx = c; idx+; public s

5、ynchronized char pop() idx-; return dataidx; public static void main(String args) MyStack m = new MyStack(); /* 下面对象m被加锁。严格的说是对象m的所有synchronized块被加锁。 如果存在另一个试图访问m的线程T,那么T无法执行m对象的push和 pop方法。 */ m.pop();/对象m被加锁。 Java的加锁解锁跟多个人排队等一个公共厕位完全一样。第一个人进去后顺手把门从里面锁住,其它人只好排队等。第一个人结束后出来时,门才会打开(解锁)。轮到第二个人进去,同样他又会把

6、门从里面锁住,其它人继续排队等待。用厕所理论可以很容易明白: 一个人进了一个厕位,这个厕位就会锁住,但不会导致另一个厕位也被锁住,因为一个人不能同时蹲在两个厕位里。对于Java 就是说:Java中的锁是针对同一个对象的,不是针对class的。看下例:MyStatck m1 = new MyStack();MyStatck m2 = new Mystatck();m1.pop();m2.pop(); m1对象的锁是不会影响m2的锁的,因为它们不是同一个厕位。就是说,假设有 3线程t1,t2,t3操作m1,那么这3个线程只可能在m1上排队等,假设另2个线程 t8,t9在操作m2,那么t8,t9只会

7、在m2上等待。而t2和t8则没有关系,即使m2上的锁释放了,t1,t2,t3可能仍要在m1上排队。原因无它,不是同一个厕位耳。Java不能同时对一个代码块加两个锁,这和数据库锁机制不同,数据库可以对一条记录同时加好几种不同的锁,请参见:4 何时释放锁?一般是执行完毕同步代码块(锁住的代码块)后就释放锁,也可以用wait()方式半路上释放锁。wait()方式就好比蹲厕所到一半,突然发现下水道堵住了,不得已必须出来站在一边,好让修下水道师傅(准备执行notify的一个线程)进去疏通马桶,疏通完毕,师傅大喊一声: 已经修好了(notify),刚才出来的同志听到后就重新排队。注意啊,必须等师傅出来啊,

8、师傅不出来,谁也进不去。也就是说notify后,不是其它线程马上可以进入封锁区域活动了,而是必须还要等notify代码所在的封锁区域执行完毕从而释放锁以后,其它线程才可进入。这里是wait与notify代码示例:public synchronized char pop() char c; while (buffer.size() = 0) try this.wait(); /从厕位里出来 catch (InterruptedException e) / ignore it. c = (Character)buffer.remove(buffer.size()-1). charValue();

9、return c;public synchronized void push(char c) this.notify(); /通知那些wait()的线程重新排队。注意:仅仅是通知它们重新排队。 Character charObj = new Character(c); buffer.addElement(charObj);/执行完毕,释放锁。那些排队的线程就可以进来了。再深入一些。由于wait()操作而半路出来的同志没收到notify信号前是不会再排队的,他会在旁边看着这些排队的人(其中修水管师傅也在其中)。注意,修水管的师傅不能插队,也得跟那些上厕所的人一样排队,不是说一个人蹲了一半出来后,

10、修水管师傅就可以突然冒出来然后立刻进去抢修了,他要和原来排队的那帮人公平竞争,因为他也是个普通线程。如果修水管师傅排在后面,则前面的人进去后,发现堵了,就wait,然后出来站到一边,再进去一个,再wait,出来,站到一边,只到师傅进去执行notify. 这样,一会儿功夫,排队的旁边就站了一堆人,等着notify.终于,师傅进去,然后notify了,接下来呢?1. 有一个wait的人(线程)被通知到。2. 为什么被通知到的是他而不是另外一个wait的人?取决于JVM.我们无法预先 判断出哪一个会被通知到。也就是说,优先级高的不一定被优先唤醒,等待 时间长的也不一定被优先唤醒,一切不可预知!(当然

11、,如果你了解该JVM的 实现,则可以预知)。3. 他(被通知到的线程)要重新排队。4. 他会排在队伍的第一个位置吗?回答是:不一定。他会排最后吗?也不一定。 但如果该线程优先级设的比较高,那么他排在前面的概率就比较大。5. 轮到他重新进入厕位时,他会从上次wait()的地方接着执行,不会重新执行。 恶心点说就是,他会接着拉巴巴,不会重新拉。6. 如果师傅notifyAll(). 则那一堆半途而废出来的人全部重新排队。顺序不可知。Java DOC 上说,The awakened threads will not be able to proceed until the current threa

12、d relinquishes the lock on this object(当前线程释放锁前,唤醒的线程不能去执行)。这用厕位理论解释就是显而易见的事。5 Lock的使用用synchronized关键字可以对资源加锁。用Lock关键字也可以。它是JDK1.5中新增内容。用法如下:class BoundedBuffer final Lock lock = new ReentrantLock(); final Condition notFull = lock.newCondition(); final Condition notEmpty = lock.newCondition(); final

13、 Object items = new Object100; int putptr, takeptr, count; public void put(Object x) throws InterruptedException lock.lock(); try while (count = items.length) notFull.await(); itemsputptr = x; if (+putptr = items.length) putptr = 0; +count; notEmpty.signal(); finally lock.unlock(); public Object tak

14、e() throws InterruptedException lock.lock(); try while (count = 0) notEmpty.await(); Object x = itemstakeptr; if (+takeptr = items.length) takeptr = 0; -count; notFull.signal(); return x; finally lock.unlock(); (注:这是JavaDoc里的例子,是一个阻塞队列的实现例子。所谓阻塞队列,就是一个队列如果满了或者空了,都会导致线程阻塞等待。Java里的 ArrayBlockingQueue提

15、供了现成的阻塞队列,不需要自己专门再写一个了。)一个对象的lock.lock()和lock.unlock()之间的代码将会被锁住。这种方式比起synchronize好在什么地方?简而言之,就是对wait的线程进行了分类。用厕位理论来描述,则是那些蹲了一半而从厕位里出来等待的人原因可能不一样,有的是因为马桶堵了,有的是因为马桶没水了。通知(notify)的时候,就可以喊:因为马桶堵了而等待的过来重新排队(比如马桶堵塞问题被解决了),或者喊,因为马桶没水而等待的过来重新排队(比如马桶没水问题被解决了)。这样可以控制得更精细一些。不像synchronize里的wait和notify,不管是马桶堵塞还是马桶没水都只能喊:刚才等待的过来排队!假如排队的人进来一看,发现原来只是马桶堵塞问题解决了,而自己渴望解决的问题(马桶没水)还没解决,只好再回去等待(wait),白进来转一圈,浪费时间与资源。Lock方式与synchronized对应关系:LockawaitsignalsignalAllsynchronizedwaitnotifynotifyAll

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2