java线程sleep yield_java开发 多线程: wait()、sleep()、 join()和yield()区别...

一、首先介绍几个概念:

1.锁池

所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。

2.等待池

当我们调用wait()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify()或notifyAll()后等待池的线程才会开始去竞争锁,notify()是随机从等待池选出一个线程放到锁池,而notifyAll()是将等待池的所有线程放到锁池当中

二、 wait()、sleep()、 join()和yield()区别

1、wait()

1.wait()必须在synchronized 修饰的同步代码块中调用

2.wait()会释放cpu资源和释放同步锁(类锁和对象锁)

3.调用wait()后必须调用notify()或notifyAll()后线程才会从等待池进入到锁池,当我们的线程竞争得到同步锁后就会重新进入绪状态等待cpu资源分配

4.wait()是Object类的方法

2、sleep()

1.sleep()会释放cpu资源,但是不会释放同步锁(类锁和对象锁)

2.sleep()是Thread类的方法

3.sleep()调用后线程会进入阻塞队列,时间到之后线程会进入就绪队列,重新去竞争cpu资源,而wait()方法不会。

3.yield()

yield()执行后线程直接进入就绪状态

4.join()

执行后线程进入阻塞状态,例如在线程B中调用线程A的join(),那线程B会进入到阻塞队列,直到join结束或中断线程B才开始进入阻塞队列

接下来验证一下sleep()会不会释放同步锁:

Test类中有个synchronized 修饰的方法和一个普通的方法,他们分别循环输出当前的线程名和方法名+i

创建俩个线程类,俩个线程类的run()方法操作都都是同一个Test对象,第一个线程类调用的是test对象的getMessage()方法,该方法是属于同步方法。第二个线程类调用test的getName()方法,该方法是一个普通方法。

最后我们在主函数中创建三个线程对象执行,前俩个对象的run()方法是调用test对象的getMessage()方法,后一个对象调用的是test的getName()方法。运行得到结果:

最后我们在主函数中创建三个线程对象执行,前俩个对象的run()方法是调用test对象的getMessage()方法,后一个对象调用的是test的getName()方法。运行得到结果:

仔细观察输出结果你会发现规律,先是第一个线程执行了getMessage()方法,之后调用sleep()让出cpu资源,这时候第三个线程得到cpu资源然后执行getName()方法,同样打印完后第三个线程又会让出cpu资源,然后俩个线程又继续竞争cpu资源。直到线程一和线程三执行完毕后线程二才开始执行。因此我们可以知道,sleep()方法调用的时候可以释放cpu资源给其他线程,但是不会释放同步锁(例子中线程1和线程2需要竞争获取对象锁,线程1先拿到了对象锁,所以线程2要等待线程1执行完毕释放对象锁后才能执行)。所以当我们在同步方法中调用sleep()方法后,其他线程依然访问不了这个同步方法。

接下来 验证wait()方法是否会释放同步锁:

我们修改Test类如上

创建俩个线程类,在主函数中调用:

输出结果:

第1个线程会先获取到同步锁,则第2个线程会进入“锁池”等待同步锁释放,第1个线程执行getMessage()方法判断当i=5时调用wait()方法,wait()方法释放cpu资源、释放同步锁,同时当前线程进入等待池。这时候我们的线程2获取到同步锁之后就会进入到就绪队列等待cpu分配资源然后开始执行,线程2调用getName()循环输出到i=5的时候同样调用wait()方法,此时线程2释放cpu资源、释放同步锁,然后进入等待池,接着调用notif()唤醒了线程1(即把线程1从等待池移动到了锁池),然后线程1执行循环结束后调用notif()唤醒线程2 。

注意:notif()方法要配合wait()方法使用,一般在wait()之后调用或者在线程结束时调用才会成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值