美文网首页
Object和Thread操作线程方法

Object和Thread操作线程方法

作者: 火兰人一个 | 来源:发表于2017-08-21 21:23 被阅读0次

管程(monitor,也被称作监视器)是一种程序结构,结构内的多个子程序(对象模块)形成的多个工作线程互斥访问共享资源。管程提供了一种机制,线程可以临时放弃互斥访问,等待某些条件得到满足后,重新获得执行权恢复它的互斥访问。一个管程的程序在运行一个线程前会先获取互斥锁,直到完成线程或是线程等待某个条件被满足才会放弃互斥锁。若每个执行中的线程在放弃互斥锁之前都能保证不变量成立,则所有线程皆不会导致竞态条件成立。--摘自维基百科

一个线程调用一个对象的 wait()、notify()、notifyAll()方法的前提是该线程持有该对象的monitor。否则会抛出异常。因此下面的举例中以上三个方法都处于同步块或者同步方法中。

首先我们来说一下Object的wait方法,假设定义一个对象a,此时线程A持有对象a,当线程A调用a.wait()时,A会释放a的monitor,此时其他的线程就有机会获取a对象的monitor。假设A线程执行的同步方法中有synchronized(a),就代表A释放了锁,因为释放了monitor。

此时有另外一个线程B的执行的另一个方法也是synchronized(a)的同步方法,当A释放了monitor后,这时B就持有了a对象的monitor(当前只讨论俩个线程的情况)。当B线程执行完同步方法后,会调用a.notify(),唤醒在当前object等待获取monitor的线程。notify只唤醒一个线程,在这里是A线程,这里需要注意的是,调用了a.notify()后,如果本方法还没执行完,会继续执行,一直到方法执行结束,才会真正的释放锁,这个时候其它的线程才有机会获取锁。

notifyAll()和notify()的区别是,会唤醒所有等待在a对象上的线程。但同一时间只有一个线程能持有monitor。其它的线程继续等待。

接下来说一下Thread类里的几个方法,首先说一下sleep()方法,当当前线程调用sleep方法时,线程并不会释放持有对象的monitor,只是让出了cpu时间,jdk中有注释,The thread does not lose ownership of any monitors,表示该线程sleep后不会失去任何monitor的所有权,即不会释放锁。join()方法不涉及锁操作,仅仅是当前线程F将cpu让给join进来的线程G,如果设置了超时时间,则在超时时候到了以后G仍然没执行完,那么F直接获取cpu。如果F和G锁执行的方法需要获取同一对象的monitor,那么即使Gjoin进来了,G仍然无法执行,因为它需要获取monitor。join操作并没有释放锁。

相关文章

网友评论

      本文标题:Object和Thread操作线程方法

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