美文网首页
java sleep和wait相关知识汇总

java sleep和wait相关知识汇总

作者: Easy的幸福 | 来源:发表于2019-10-11 15:49 被阅读0次

java sleep和wait的区别?

  • sleep是Thread类的方法,wait是Object类中的方法,尽管这这两个方法都会影响线程的状态,但是本质上是有区别的。

  • Thread.sleep不会导致锁行为的改变,如果当前线程是有锁的,那么sleep是不会让出锁的。

  • sleep和wait都会暂停当前的线程,对于CPU资源来说,不管这两种哪种方式暂停的线程,都表示它暂时不需要CPU的执行时间。这时候OS会将执行时间分配给其它线程。区别是,调用wait之后,需要别的线程执行notify或者notifyAll才能使其重新获取CPU的执行时间。

  • Sleep不释放锁,线程是进入阻塞状态,确切的说是TIMED_WAITING。

  • Java的synchronized -- wait的结构,即“获取锁-判断-判断不满足就释放锁-然后等通知重来”,用特定的代码形式来实现“条件同步”:

synchronized { // 获取锁
  while (判定条件) wait(); // 如果条件不满足就释放锁,并且等着
  // ... 要进入的代码
  notify(); // 或者notifyAll,通知其他wait者可以重来
}

如果不写synchronized,就是运行时错误IllegalMonitorStateException;万一忘记了while或者忘记notify,代码正确性就可能有问题,并且连运行时错误都没有。


线程间的状态切换:

  • 新建(new):新创建了一个线程对象。
  • 可运行(runnable):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权。
  • 运行(running):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
  • 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种:

等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。

同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。

其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

  • 死亡(dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

并发编程中常用的几个jdk中的api

  • Thread.sleep(long millis) 静态方法。当前线程调用此方法,使当前线程进入阻塞状态(其他阻塞),但不释放任何锁资源,一定时间后线程自动进入runnable状态。给其它线程执行机会的最佳方式.
  • obj.wait()或obj.wait(long timeout) 当前线程调用某对象的wait()方法,当前线程释放对象锁(wait一定在synchronized代码块/方法中,故一定得到了锁,才进来的此方法),进入阻塞状态(等待队列)。等待notify或wait设置的timeout到期,方可进入另外一个阻塞状态(锁池)。
  • t.join()或t.join(long millis) 非静态方法。当前线程A执行过程中,调用B线程的join方法,使当前线程进入阻塞状态(其他阻塞),但不释放对象锁,等待B线程执行完后或一定时间millis后,A线程进入runnable状态。
  • Thread.yield() 静态方法。当前线程调用此方法,使线程由running态进入runnable态,放弃cpu使用权,让cpu再次选择要执行的线程。 注:实际过程中,yield仅仅是让其它具有同等优先级的runnable线程获取执行权,但并不能保证其它具有同等优先级的线程就一定能获得cpu执行权。因为做出让步的当前线程,可能会被cpu再次选中,进入running状态。yield()不会导致阻塞。

相关文章

网友评论

      本文标题:java sleep和wait相关知识汇总

      本文链接:https://www.haomeiwen.com/subject/vgitmctx.html