前言
今天简单的讲一讲线程中sleep(),join(),yield(),wait(),notify(),notifyAll()这些方法的使用以及区别。
不过在讲这些方法之前,需要简单的介绍一下锁池和等待池的概念。
锁池和等待池
1.锁池
所有需要竞争同步锁的线程都会放在锁池当中,比如当前对象的锁已经被其中一个线程得到,则其他线程需要在这个锁池进行等待,当前面的线程释放同步锁后锁池中的线程去竞争同步锁,当某个线程得到后会进入就绪队列进行等待cpu资源分配。
2.等待池
当我们调用wait()方法后,线程会放到等待池当中,等待池的线程是不会去竞争同步锁。只有调用了notify()或notifyAll()后等待池的线程才会开始去竞争锁,notify()是随机从等待池选出一个线程放到锁池,而notifyAll()是将等待池的所有线程放到锁池当中
sleep()方法
sleep()这个方法的使用很简单,因为它是一个Thread的静态方法,所以就可以直接Thread.sleep(毫秒值),休眠指定的毫秒数。
1、使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会执行。但是时间到了之后线程会进入就绪队列,重新去竞争cpu资源。
2.sleep()会释放cpu资源,但是不会释放同步锁(类锁和对象锁)
yield()
使当前正在执行的线程向另一个线程交出运行权。注意这是一个静态方法。
该方法与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
1、yield()执行后线程直接进入就绪状态。
2、yield()会释放cpu资源,但是不会释放同步锁(类锁和对象锁)
join()
执行后线程进入阻塞状态,例如在线程B中调用线程A的join(),那线程B会进入到阻塞队列,直到join结束或中断线程B才开始进入阻塞队列。
可以实现一个线程的顺序执行。
wait()和notify()、notifyAll()
1、wait方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用
2、wait()方法使当前线程暂停执行并释放会cpu资源,以及同步锁(类锁和对象锁)
3、调用wait()后必须调用notify()或notifyAll()后线程才会从等待池进入到锁池,当我们的线程竞争得到同步锁后就会重新进入绪状态等待cpu资源分配
当调用notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有锁标志等待池中线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
注意:
1、这三个方法都是java.lang.Object的方法。
2、notif()方法要配合wait()方法使用,一般在wait()之后调用或者在线程结束时调用才会成功。