如何在Java项目中实现多线程的阻塞与唤醒?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
<强> Java线程的阻塞及唤醒
强>
<强> 1。睡眠()方法:
强>
睡眠(…毫秒),指定以毫秒为单位的时间,使线程在该时间内进入线程阻塞状态,期间得不到cpu的时间片,等到时间过去了,线程重新进入可执行状态。(暂停线程,不会释放锁)
//测试睡()方法 类Thread7实现Runnable { @Override 公共空间run () { (int i=0; i<50,我+ +){ System.out.println (Thread.currentThread () . getname () +“num=? i); 尝试{ thread . sleep (500); }捕捉(InterruptedException e) { e.printStackTrace (); } } } } 类Thread8实现Runnable { @Override 公共空间run () { for (int i=0; i<1000;我+ +){ System.out.println (Thread.currentThread () . getname () +“num=? i); } } } 公共静态void main (String [] args) {/* *测试线程阻塞 *///测试睡()方法 Thread7 t7=new Thread7 (); Thread8 t8=new Thread8 (); 线程t81=新线程(t8,“饺子“); 线程t71=新线程(t7,“包子“); 线程t72=新线程(t7,“面包“); t71.start (); t81.start (); t72.start (); }
<强> 2.暂停()和简历()方法:。强>
挂起和唤醒线程,暂停()使线程进入阻塞状态,只有对应的简历()被调用的时候,线程才会进入可执行状态。(不建议用,容易发生死锁)
//测试挂起()和恢复()方法 类Thread9实现Runnable { @Override 公共空间run () { (长时间我=0;i<500000000;我+ +){ System.out.println (Thread.currentThread () . getname () +“;num=? i); } } } 公共静态void main (String [] args) {//测试挂起和恢复 Thread9 t9=new Thread9 (); 线程t91=新线程(t9,“包子“); t91.start (); 尝试{ thread . sleep (2000); }捕捉(InterruptedException e) {//TODO自动生成的catch块 e.printStackTrace (); } t91.suspend (); 尝试{ thread . sleep (2000); }捕捉(InterruptedException e) {//TODO自动生成的catch块 e.printStackTrace (); } t91.resume (); }
(在控制台打印输出的时候,会停顿2秒钟,然后再继续打印)。
<强> 3。产量()方法:
强>
会使的线程放弃当前分得的cpu时间片,但此时线程任然处于可执行状态,随时可以再次分得cpu时间片.yield()方法只能使同优先级的线程有执行的机会。调用收益率()的效果等价于调度程序认为该线程已执行了足够的时间从而转到另一个线程。(暂停当前正在执行的线程,并执行其他线程,且让出的时间不可知)
//测试产量()方法 类Thread10实现Runnable { @Override 公共空间run () { for (int i=0; i<100;我+ +){ System.out.println (Thread.currentThread () . getname () +“;num=? i); 如果(我==33){ thread . yield (); } } } } 公共静态void main (String [] args) {//测试产量 Thread10 t10=new Thread10 (); 线程t101=新线程(t10、“包子“); 线程t102=新线程(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()内可加或不加参数,加参数时是以毫秒为单位,当到了指定时间或调用通知()方法时,进入可执行状态。(属于对象类,而不属于线程类,等()会先释放锁住的对象,然后再执行等待的动作,由于等()所等待的对象必须先锁住,因此,它只能用在同步化程序段或者同步化方法内,否则,会抛出异常IllegalMonitorStateException。)
//测试wait()和notify()方法//用生产者和消费者模式模拟这一过程/*消费者*/类消费者实现Runnable { 私人向量obj; 公共消费(v) { 这一点。obj=v; } 公共空间run () { 同步(obj) { 而(真){ 尝试{ 如果(obj.size ()==0) { obj.wait (); } System.out.println(“消费者:我要买面包!”); System.out.println(“面包数:“;+ obj.size ()); obj.clear (); obj.notify (); }捕捉(异常e) { e.printStackTrace (); } } } } }/*生产者*/类生产者实现Runnable { 私人向量obj; 公共生产者(v) { 这一点。obj=v; } 公共空间run () { 同步(obj) { 而(真){ 尝试{ 如果(obj.size () !=0) { obj.wait (); } obj。添加(新字符串(“面包“)); obj.notify (); System.out.println(“生产者:面包做好了!”); thread . sleep (500); }捕捉(异常e) { e.printStackTrace (); } } } } } 公共静态void main (String [] args) {//测试wait()和notify () 矢量obj=new (); 线程消费=新线程(新的消费者(obj)); 生产者线程=新线程(新生产者(obj)); consumer.start (); producter.start (); }如何在Java项目中实现多线程的阻塞与唤醒