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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

java中yieldsleep以及wait的区别.docx

1、java中yieldsleep以及wait的区别往往混淆了这三个函数的使用。从操作系统的角度讲,os会维护一个readyqueue(就绪的线程队列)。并且在某一时刻cpu只为readyqueue中位于队列头部的线程服务。但是当前正在被服务的线程可能觉得cpu的服务质量不够好,于是提前退出,这就是yield。或者当前正在被服务的线程需要睡一会,醒来后继续被服务,这就是sleep。?sleep方法不推荐使用,可用wait。线程退出最好自己实现,在运行状态中一直检验一个状态,如果这个状态为真,就一直运行,如果外界更改了这个状态变量,那么线程就停止运行。sleep()使当前线程进入停滞状态,所以执行s

2、leep()的线程在指定的时间内肯定不会执行;yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。当调用wait()后,线程会释放掉它所占有的“锁标志”,从而使线程所在对象中的其它synchronized数据可被别的线程使用。waite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数或synchronizedblock中进行调用。如果在n

3、on-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。彻底明白多线程通信机制:?线程间的通信1.?线程的几种状态线程有四种状态,任何一个线程肯定处于这四种状态中的一种:1)?产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。2)?可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待

4、排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。3)?死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。4)?停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。2.?classThread下的常用函数函数

5、2.1?suspend()、resume()1)?通过suspend()函数,可使线程进入停滞状态。通过suspend()使线程进入停滞状态后,除非收到resume()消息,否则该线程不会变回可执行状态。2)?当调用suspend()函数后,线程不会释放它的“锁标志”。例11:?classTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThreadMethod(Stringname)?super(name);?publicsynchronizedvoidrun()?if(shareVar=0)?for(int

6、i=0;i5;i+)?shareVar+;?if(shareVar=5)?this.suspend();/(1)?else?shareVar=+shareVar);?this.resume();/(2)?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);TestThreadMethodt2=newTestThreadMethod(t2);t1.start();/(5)?/t1.start();/(3)?t2.start();/(4)?运行结果为:t2

7、shareVar=5i.?当代码(5)的t1所产生的线程运行到代码(1)处时,该线程进入停滞状态。然后排程器从线程池中唤起代码(4)的t2所产生的线程,此时shareVar值不为0,所以执行else中的语句。ii.?也许你会问,那执行代码(2)后为什么不会使t1进入可执行状态呢?正如前面所说,t1和t2是两个不同对象的线程,而代码(1)和(2)都只对当前对象进行操作,所以t1所产生的线程执行代码(1)的结果是对象t1的当前线程进入停滞状态;而t2所产生的线程执行代码(2)的结果是把对象t2中的所有处于停滞状态的线程调回到可执行状态。iii.?那现在把代码(4)注释掉,并去掉代码(3)的注释,是

8、不是就能使t1重新回到可执行状态呢?运行结果是什么也不输出。为什么会这样呢?也许你会认为,当代码(5)所产生的线程执行到代码(1)时,它进入停滞状态;而代码(3)所产生的线程和代码(5)所产生的线程是属于同一个对象的,那么就当代码(3)所产生的线程执行到代码(2)时,就可使代码(5)所产生的线程执行回到可执行状态。但是要清楚,suspend()函数只是让当前线程进入停滞状态,但并不释放当前线程所获得的“锁标志”。所以当代码(5)所产生的线程进入停滞状态时,代码(3)所产生的线程仍不能启动,因为当前对象的“锁标志”仍被代码(5)所产生的线程占有。2.2?sleep()1)?sleep()函数有一

9、个参数,通过参数可使线程在指定的时间内进入停滞状态,当指定的时间过后,线程则自动进入可执行状态。2)?当调用sleep()函数后,线程不会释放它的“锁标志”。例12:?classTestThreadMethodextendsThread?classTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThreadMethod(Stringname)?super(name);?publicsynchronizedvoidrun()?for(inti=0;i3;i+)?:+i);?try?Thread.sleep(10

10、0);/(4)?catch(InterruptedExceptione)?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);?TestThreadMethodt2=newTestThreadMethod(t2);?t1.start();(1)?t1.start();(2)?/t2.start();(3)?运行结果为:t1:0t1:1t1:2t1:0t1:1由结果可证明,虽然在run()中执行了sleep(),但是它不会释放对象的“锁标志”,所以除非代

11、码(1)的线程执行完run()函数并释放对象的“锁标志”,否则代码(2)的线程永远不会执行。?如果把代码(2)注释掉,并去掉代码(3)的注释,结果将变为:t1:0t2:0t1:1t2:1t1:2t2:2由于t1和t2是两个对象的线程,所以当线程t1通过sleep()进入停滞时,排程器会从线程池中调用其它的可执行线程,从而t2线程被启动。?例13:?classTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThreadMethod(Stringname)?super(name);?publicsynchroni

12、zedvoidrun()?for(inti=0;i5;i+)?:+i);?try?if(Thread.currentThread().getName().equals(t1)?Thread.sleep(200);?else?Thread.sleep(100);?catch(InterruptedExceptione)?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);?TestThreadMethodt2=newTestThreadMethod(t2

13、);?t1.start();?/t1.start();?t2.start();?运行结果为:t1:0t2:0t2:1t1:1t2:2t2:3t1:2t2:4t1:3t1:4由于线程t1调用了sleep(200),而线程t2调用了sleep(100),所以线程t2处于停滞状态的时间是线程t1的一半,从从结果反映出来的就是线程t2打印两倍次线程t1才打印一次。2.3?yield()1)?通过yield()函数,可使线程进入可执行状态,排程器从可执行状态的线程中重新进行排程。所以调用了yield()的函数也有可能马上被执行。2)?当调用yield()函数后,线程不会释放它的“锁标志”。例14:?cl

14、assTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThreadMethod(Stringname)?super(name);?publicsynchronizedvoidrun()?for(inti=0;i4;i+)?:+i);?Thread.yield();?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);?TestThreadMethodt2=newTes

15、tThreadMethod(t2);?t1.start();?t1.start();/(1)?/t2.start();(2)?运行结果为:t1:0t1:1t1:2t1:3t1:0t1:1t1:2t1:3从结果可知调用yield()时并不会释放对象的“锁标志”。?如果把代码(1)注释掉,并去掉代码(2)的注释,结果为:t1:0t1:1t2:0t1:2t2:1t1:3t2:2t2:3从结果可知,虽然t1线程调用了yield(),但它马上又被执行了。2.4?sleep()和yield()的区别1)?sleep()使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行;yiel

16、d()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。2)?sleep()可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会;yield()只能使同优先级的线程有执行的机会。例15:?classTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThreadMethod(Stringname)?super(name);?publicvoidrun()?for(inti=0;i4;i+)?:+i);?/Thread.yield()

17、;(1)?/*(2)*/?try?Thread.sleep(3000);?catch(InterruptedExceptione)?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);?TestThreadMethodt2=newTestThreadMethod(t2);?t1.setPriority(Thread.MAX_PRIORITY);?t2.setPriority(Thread.MIN_PRIORITY);?t1.start();?t2.st

18、art();?运行结果为:t1:0t1:1t2:0t1:2t2:1t1:3t2:2t2:3由结果可见,通过sleep()可使优先级较低的线程有执行的机会。注释掉代码(2),并去掉代码(1)的注释,结果为:t1:0t1:1t1:2t1:3t2:0t2:1t2:2t2:3可见,调用yield(),不同优先级的线程永远不会得到执行机会。2.5?join()使调用join()的线程执行完毕后才能执行其它线程,在一定意义上,它可以实现同步的功能。例16:?classTestThreadMethodextendsThread?publicstaticintshareVar=0;?publicTestThr

19、eadMethod(Stringname)?super(name);?publicvoidrun()?for(inti=0;i4;i+)?+i);?try?Thread.sleep(3000);?catch(InterruptedExceptione)?publicclassTestThread?publicstaticvoidmain(Stringargs)?TestThreadMethodt1=newTestThreadMethod(t1);?t1.start();?try?t1.join();?catch(InterruptedExceptione)?t1.start();?运行结果为:

20、012301233.classObject下常用的线程函数3.1wait()、notify()和notifyAll()1)wait()函数有两种形式:第一种形式接受一个毫秒值,用于在指定时间长度内暂停线程,使线程进入停滞状态。第二种形式为不带参数,代表waite()在notify()或notifyAll()之前会持续停滞。2)当对一个对象执行notify()时,会从线程等待池中移走该任意一个线程,并把它放到锁标志等待池中;当对一个对象执行notifyAll()时,会从线程等待池中移走所有该对象的所有线程,并把它们放到锁标志等待池中。3)当调用wait()后,线程会释放掉它所占有的“锁标志”,从

21、而使线程所在对象中的其它synchronized数据可被别的线程使用。例17:下面,我们将对例11中的例子进行修改classTestThreadMethodextendsThreadpublicstaticintshareVar=0;publicTestThreadMethod(Stringname)super(name);publicsynchronizedvoidrun()if(shareVar=0)for(inti=0;i10;i+)shareVar+;if(shareVar=5)trythis.wait();/(4)catch(InterruptedExceptione)if(shar

22、eVar!=0)shareVar=+shareVar);this.notify();/(5)publicclassTestThreadpublicstaticvoidmain(Stringargs)TestThreadMethodt1=newTestThreadMethod(t1);TestThreadMethodt2=newTestThreadMethod(t2);t1.start();/(1)/t1.start();(2)t2.start();/(3)运行结果为:t2shareVar=5因为t1和t2是两个不同对象,所以线程t2调用代码(5)不能唤起线程t1。如果去掉代码(2)的注释,并注

23、释掉代码(3),结果为:t1shareVar=5t1shareVar=10这是因为,当代码(1)的线程执行到代码(4)时,它进入停滞状态,并释放对象的锁状态。接着,代码(2)的线程执行run(),由于此时shareVar值为5,所以执行打印语句并调用代码(5)使代码(1)的线程进入可执行状态,然后代码(2)的线程结束。当代码(1)的线程重新执行后,它接着执行for()循环一直到shareVar=10,然后打印shareVar。3.2wait()、notify()和synchronizedwaite()和notify()因为会对对象的“锁标志”进行操作,所以它们必须在synchronized函数

24、或synchronizedblock中进行调用。如果在non-synchronized函数或non-synchronizedblock中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。例18:classTestThreadMethodextendsThreadpublicintshareVar=0;publicTestThreadMethod(Stringname)super(name);newNotifier(this);publicsynchronizedvoidrun()if(shareVar=0)for(inti=0;i5;i+

25、)shareVar+;=+shareVar);trythis.wait();catch(InterruptedExceptione)classNotifierextendsThreadprivateTestThreadMethodttm;Notifier(TestThreadMethodt)ttm=t;start();publicvoidrun()while(true)trysleep(2000);catch(InterruptedExceptione)/*1要同步的不是当前对象的做法*/synchronized(ttm)ttm.notify();publicclassTestThreadpublicstaticvoidmain(Stringargs)TestThreadMethodt1=newTestThreadMethod(t1);t1.start();运行结果为:i=1wait.notify.i=2wait.notify.i=3wait.notify.i=4wait.notify.i=5wait.notify.4.wait()、notify()、notifyAll()和suspend()、resume()、sleep

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1