Java多线程阻塞与唤醒代码示例
java线程的阻塞及唤醒
1.sleep()方法:
sleep(…毫秒),指定以毫秒为单位的时间,使线程在该时间内进入线程阻塞状态,期间得不到cpu的时间片,等到时间过去了,线程重新进入可执行状态。(暂停线程,不会释放锁)
//测试sleep()方法 classThread7implementsRunnable{ @Override publicvoidrun(){ for(inti=0;i<50;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); try{ Thread.sleep(500); }catch(InterruptedExceptione){ e.printStackTrace(); } } } } classThread8implementsRunnable{ @Override publicvoidrun(){ for(inti=0;i<1000;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); } } } publicstaticvoidmain(String[]args){ /* *测试线程阻塞 */ //测试sleep()方法 Thread7t7=newThread7(); Thread8t8=newThread8(); Threadt81=newThread(t8,"饺子"); Threadt71=newThread(t7,"包子"); Threadt72=newThread(t7,"面包"); t71.start(); t81.start(); t72.start(); }
2.suspend()和resume()方法:。
挂起和唤醒线程,suspend()使线程进入阻塞状态,只有对应的resume()被调用的时候,线程才会进入可执行状态。(不建议用,容易发生死锁)
//测试suspend()和resume()方法 classThread9implementsRunnable{ @Override publicvoidrun(){ for(longi=0;i<500000000;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); } } } publicstaticvoidmain(String[]args){ //测试suspend和resume Thread9t9=newThread9(); Threadt91=newThread(t9,"包子"); t91.start(); try{ Thread.sleep(2000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } t91.suspend(); try{ Thread.sleep(2000); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } t91.resume(); }
(在控制台打印输出的时候,会停顿2秒钟,然后再继续打印。)
3.yield()方法:
会使的线程放弃当前分得的cpu时间片,但此时线程任然处于可执行状态,随时可以再次分得cpu时间片。yield()方法只能使同优先级的线程有执行的机会。调用yield()的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。(暂停当前正在执行的线程,并执行其他线程,且让出的时间不可知)
//测试yield()方法 classThread10implementsRunnable{ @Override publicvoidrun(){ for(inti=0;i<100;i++){ System.out.println(Thread.currentThread().getName()+"num="+i); if(i==33){ Thread.yield(); } } } } publicstaticvoidmain(String[]args){ //测试yield Thread10t10=newThread10(); Threadt101=newThread(t10,"包子"); Threadt102=newThread(t10,"面包"); t101.start(); t102.start(); } /* 运行结果为: …… 包子num=24 包子num=25 包子num=26 包子num=27 包子num=28 包子num=29 包子num=30 包子num=31 包子num=32 包子num=33 面包num=0 面包num=1 面包num=2 面包num=3 …… 面包num=30 面包num=31 面包num=32 面包num=33 包子num=34 包子num=35 包子num=36 包子num=37 包子num=38 …… */
(可以看到,当数字为33时,都发生了交替。)
4.wait()和notify()方法:
两个方法搭配使用,wait()使线程进入阻塞状态,调用notify()时,线程进入可执行状态。wait()内可加或不加参数,加参数时是以毫秒为单位,当到了指定时间或调用notify()方法时,进入可执行状态。(属于Object类,而不属于Thread类,wait()会先释放锁住的对象,然后再执行等待的动作。由于wait()所等待的对象必须先锁住,因此,它只能用在同步化程序段或者同步化方法内,否则,会抛出异常IllegalMonitorStateException.)
//测试wait()和notify()方法 //用生产者和消费者模式模拟这一过程 /*消费者*/ classConsumerimplementsRunnable{ privateVectorobj; publicConsumer(Vectorv){ this.obj=v; } publicvoidrun(){ synchronized(obj){ while(true){ try{ if(obj.size()==0){ obj.wait(); } System.out.println("消费者:我要买面包。"); System.out.println("面包数:"+obj.size()); obj.clear(); obj.notify(); }catch(Exceptione){ e.printStackTrace(); } } } } } /*生产者*/ classProducterimplementsRunnable{ privateVectorobj; publicProducter(Vectorv){ this.obj=v; } publicvoidrun(){ synchronized(obj){ while(true){ try{ if(obj.size()!=0){ obj.wait(); } obj.add(newString("面包")); obj.notify(); System.out.println("生产者:面包做好了。"); Thread.sleep(500); }catch(Exceptione){ e.printStackTrace(); } } } } } publicstaticvoidmain(String[]args){ //测试wait()和notify() Vectorobj=newVector(); Threadconsumer=newThread(newConsumer(obj)); Threadproducter=newThread(newProducter(obj)); consumer.start(); producter.start(); }
5.join()方法
也叫线程加入。是当前线程A调用另一个线程B的join()方法,当前线程转A入阻塞状态,直到线程B运行结束,线程A才由阻塞状态转为可执行状态。
//测试join classThread11implementsRunnable{ @Override publicvoidrun(){ System.out.println("StartProgress."); try{ for(inti=0;i<5;i++){ System.out.println("Thread11线程:"+i); Thread.sleep(1000); } }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } System.out.println("EndProgress."); } } publicstaticvoidmain(String[]args){ //测试join Thread11t11=newThread11(); Threadt111=newThread(t11); t111.start(); try{ t111.join(); }catch(InterruptedExceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } System.out.println("hi,I'mMain线程"); } /* 运行结果为: StartProgress. Thread11线程:0 Thread11线程:1 Thread11线程:2 Thread11线程:3 Thread11线程:4 EndProgress. hi,I'mMain线程 */
总结
本文关于Java多线程阻塞与唤醒代码示例的介绍就到这里,希望对大家学习Java有所帮助。感兴趣的朋友可以继续参阅:Java多线程ForkJoinPool实例详解 、Java通过卖票理解多线程 、Java线程安全基础概念解析等。有什么问题可以随时留言,或者有什么方面想要了解的,您也可以留言,小编会及时给您答复。希望大家对毛票票多多支持!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。