java.util.concurrent.Semaphore是一个计数信号量<wbr style="line-height:25px"><span style="color:#003366; line-height:25px">。从概念上讲,信号量维护了一个许可集。<br style="line-height:25px">
通过acquire()来获得一个许可,如果有许可可用,就返回,否则阻塞直到有许可可用。<br style="line-height:25px">
通过release()来释放一个许可。</span><br style="line-height:25px">
但是,<wbr style="line-height:25px"><span style="color:#000080; line-height:25px">不使用实际的许可对象,Semaphore只对可用许可的号码进行计数</span><wbr style="line-height:25px">,并采取相应的行动。<br style="line-height:25px">
Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。<br style="line-height:25px">
例如,下面的类使用信号量控制对内容池的访问:<br style="line-height:25px"><span style="line-height:normal; color:rgb(51,51,51); font-family:arial,sans-serif; font-size:13px"></span>
<pre class="prettyprint" style="line-height:inherit; padding-top:10px; padding-right:10px; padding-bottom:10px; padding-left:10px; border-top-width:1px; border-right-width:1px; border-bottom-width:1px; border-left-width:1px; border-top-style:solid; border-right-style:solid; border-bottom-style:solid; border-left-style:solid; border-top-color:rgb(204,204,204); border-right-color:rgb(204,204,204); border-bottom-color:rgb(204,204,204); border-left-color:rgb(204,204,204); color:rgb(0,112,0); font-family:monospace; background-color:rgb(250,250,250); margin-top:0px; margin-bottom:1em; margin-left:1em; overflow-x:auto; overflow-y:auto"><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"></span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">class</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Pool</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">private</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">static</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">final</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">int</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> MAX_AVAILABLE </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,102,102)"><span class="lit" style="line-height:23px; color:rgb(0,102,102)">100</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">private</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">final</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Semaphore</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> available </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">new</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Semaphore</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">MAX_AVAILABLE</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">,</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">true</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">);</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">public</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Object</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> getItem</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">()</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">throws</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">InterruptedException</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> available</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">.</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">acquire</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">();</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> getNextAvailableItem</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">();</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">public</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">void</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> putItem</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Object</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> x</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">)</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">if</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">markAsUnused</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">x</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">))</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> available</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">.</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">release</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">();</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(136,0,0)"><span class="com" style="line-height:23px; color:rgb(136,0,0)">// Not a particularly efficient data structure; just for demo</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">protected</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Object</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[]</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> items </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">...</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> whatever kinds of items being managed</span><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">protected</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">boolean</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[]</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> used </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">new</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">boolean</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">MAX_AVAILABLE</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">];</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">protected</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">synchronized</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Object</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> getNextAvailableItem</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">()</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">for</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">int</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> i </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,102,102)"><span class="lit" style="line-height:23px; color:rgb(0,102,102)">0</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> i </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)"><</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> MAX_AVAILABLE</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">++</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">)</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">if</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(!</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">used</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">])</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> used</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">]</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">true</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> items</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">];</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">null</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(136,0,0)"><span class="com" style="line-height:23px; color:rgb(136,0,0)">// not reached</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">protected</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">synchronized</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">boolean</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> markAsUnused</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(102,0,102)"><span class="typ" style="line-height:23px; color:rgb(102,0,102)">Object</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> item</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">)</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">for</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">int</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> i </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,102,102)"><span class="lit" style="line-height:23px; color:rgb(0,102,102)">0</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> i </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)"><</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> MAX_AVAILABLE</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">++</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">)</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">if</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">item </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">==</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> items</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">])</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">if</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">(</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">used</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">])</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">{</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> used</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">[</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)">i</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">]</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">=</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">false</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">true</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">else</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">false</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">return</span></span><span style="line-height:23px; color:rgb(0,0,0)"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(0,0,136)"><span class="kwd" style="line-height:23px; color:rgb(0,0,136)">false</span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">;</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"> </span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span><span style="line-height:23px; color:rgb(0,0,0)"><br style="line-height:23px"><br style="line-height:23px"><span class="pln" style="line-height:23px; color:rgb(0,0,0)"></span></span><span style="line-height:23px; color:rgb(102,102,0)"><span class="pun" style="line-height:23px; color:rgb(102,102,0)">}</span></span></pre>
</wbr></wbr></wbr>获得一项前,每个线程必须从信号量获取许可,从而保证可以使用该项。
该线程结束后,将项返回到池中并将许可返回到该信号量,从而允许其他线程获取该项。
注意,调用acquire()时无法保持同步锁,因为这会阻止将项返回到池中。
<wbr style="line-height:25px">注意1</wbr><wbr style="line-height:25px">:"<span style="color:#000080; line-height:25px">调用acquire()时无法保持同步锁,因为这会阻止将项返回到池中</span>"因为如果调用acquire()时保持同步锁,这时如果它被阻塞了,<br style="line-height:25px"> 调putItem(Objectx)时,它又调用markAsUnused()了,而markAsUnused()需要同步锁。这时就死锁了。<br style="line-height:25px"> 信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。<br style="line-height:25px"><span style="color:#003366; line-height:25px">将信号量初始化为1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。<br style="line-height:25px"> 这通常也称为二进制信号量,因为它只能有两种状态:</span><span style="color:#000080; line-height:25px">一个可用的许可,或零个可用的许可</span><span style="color:#003366; line-height:25px">。<br style="line-height:25px"> 按此方式使用时,二进制信号量具有某种属性(与很多Lock实现不同),即可以由其他线程释放“锁”,而不是由所有者(因为信号量没有所有权的概念)。</span><br style="line-height:25px"> 在某些专门的上下文(如死锁恢复)中这会很有用。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:<wbr style="line-height:25px"><span style="color:#000080; line-height:25px">因为信号量没有所有权的概念,非二进制的信号量当然也可以由其他线程释放许可,而不一定要是所有者</span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="line-height:25px; color:rgb(255,0,255)">Semaphore</span><span style="color:#003366; line-height:25px">的构造方法可选地接受一个公平参数。当设置为false时,此类不对线程获取许可的顺序做任何保证。</span><br style="line-height:25px"> 特别地,闯入是允许的,也就是说可以在已经等待的线程前为调用acquire()的线程分配一个许可,<br style="line-height:25px"> 从逻辑上说,<span style="color:#000080; line-height:25px">就是新线程将自己置于等待线程队列的头部。当公平设置为true时,信号量保证对于任何调用获取方法的线程而言,<br style="line-height:25px"> 都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。</span><br style="line-height:25px"> 注意,<span style="color:#000080; line-height:25px">FIFO排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了acquire,但是却在该线程之后到达排序点,并且从方法返回时也类似</span>。还要注意,<span style="color:#000080; line-height:25px">非同步的tryAcquire方法不使用公平设置,而是使用任意可用的许可</span>。<br style="line-height:25px"> 通常,应该将用于控制资源访问的信号量初始化为公平的,以确保所有线程都可访问资源。<br style="line-height:25px"> 为其他的种类的同步控制使用信号量时,非公平排序的吞吐量优势通常要比公平考虑更为重要。<br style="line-height:25px"> 此类还提供便捷的方法来同时acquire和释放多个许可。小心,在未将公平设置为true时使用这些方法会增加不确定延期的风险。<br style="line-height:25px"> 内存一致性效果:<span style="color:#000080; line-height:25px">线程中调用“释放”方法(比如release())之前的操作happen-before另一线程中紧跟在成功的“获取”方法(比如acquire())之后的操作。</span><br style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">注意1</span><span style="color:#000080; line-height:25px">:即使将公平参数设置为"true",会按照FIFO来选择线程,即先到达先被分配许可,但是先调用acquire,并不能保证该线程先到达<wbr style="line-height:25px">。</wbr></span><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">主要函数</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquire()</span>throwsInterruptedException<wbr style="line-height:25px"><br style="line-height:25px"> 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的许可,则在发生以下两种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *某些其他线程调用此信号量的release()方法,并且当前线程是下一个要被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待许可时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程被中断<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1:</wbr></span>它可以抛出InterruptedException<wbr style="line-height:25px"><br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquireUninterruptibly()</span><wbr style="line-height:25px"><br style="line-height:25px"> 从此信号量中获取许可,在有可用的许可前将其阻塞。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,将可用的允许数减1。<br style="line-height:25px"> 如果没有可用的许可,则在其他某些线程调用此信号量的release()方法,并且当前线程是下一个要被分配许可的线程前,<br style="line-height:25px"> 禁止当前线程用于线程安排目的并使其处于休眠状态。<br style="line-height:25px"> 如果当前线程在等待许可时被中断,那么它将继续等待,但是与没有发生中断,其将接收允许的时间相比,为该线程分配许可的时间可能改变。<br style="line-height:25px"> 当线程确实从此方法返回后,将设置其中断状态。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:"当线程确实从此方法返回后,将设置其中断状态"<br style="line-height:25px"> 这句话不正确。我觉得acquireUninterruptibly()。如果阻塞,它仅仅是忽略对中断(即中断状态)的处理。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">具体见例1</wbr></span><wbr style="line-height:25px">,关于Interrupted的更多内容请参见《Interrupt》<br style="line-height:25px"> publicbooleantryAcquire()<br style="line-height:25px"> 仅在调用时此信号量存在一个可用许可,才从信号量获取许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的许可,则此方法立即返回并且值为false。<br style="line-height:25px"> 即使已将此信号量设置为使用公平排序策略,但是调用tryAcquire()也将立即获取许可(如果有一个可用),<br style="line-height:25px"> 而不管当前是否有正在等待的线程。在某些情况下,此“闯入”行为可能很有用,即使它会打破公平性也如此。<br style="line-height:25px"> 如果希望遵守公平设置,则使用tryAcquire(0,TimeUnit.SECONDS),它几乎是等效的(它也检测中断)。<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;否则返回false<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:即使已将此信号量设置为使用公平排序策略,但是调用tryAcquire()也将立即获取许可(如果有一个可用),而不管当前是否有正在等待的线程。<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicboolean</span><span style="color:#ff6600; line-height:25px">tryAcquire</span>(longtimeout,<br style="line-height:25px"> TimeUnitunit)<br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的允许,则在发生以下三种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的release()方法并且当前线程是下一个被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程;或者<br style="line-height:25px"> *已超出指定的等待时间。<br style="line-height:25px"> 如果获取了许可,则返回值为true。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待获取许可的同时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 如果超出了指定的等待时间,则返回值为false。如果该时间小于等于0,则方法根本不等待。<br style="line-height:25px"> 参数:<br style="line-height:25px"> timeout-等待许可的最多时间<br style="line-height:25px"> unit-timeout参数的时间单位<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;如果获取许可前超出了等待时间,则返回false<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程是已中断的<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicboolean</span><span style="color:#ff6600; line-height:25px">tryAcquire</span>(longtimeout,<br style="line-height:25px"> TimeUnitunit)<br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的允许,则在发生以下三种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的release()方法并且当前线程是下一个被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程;或者<br style="line-height:25px"> *已超出指定的等待时间。<br style="line-height:25px"> 如果获取了许可,则返回值为true。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待获取许可的同时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 如果超出了指定的等待时间,则返回值为false。如果该时间小于等于0,则方法根本不等待。<br style="line-height:25px"> 参数:<br style="line-height:25px"> timeout-等待许可的最多时间<br style="line-height:25px"> unit-timeout参数的时间单位<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;如果获取许可前超出了等待时间,则返回false<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程是已中断的<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">release()</span><br style="line-height:25px"> 释放一个许可,将其返回给信号量。<br style="line-height:25px"> 释放一个许可,将可用的许可数增加1。如果任意线程试图获取许可,则选中一个线程并将刚刚释放的许可给予它。<br style="line-height:25px"> 然后针对线程安排目的启用(或再启用)该线程。<br style="line-height:25px"> 不要求释放许可的线程必须通过调用acquire()来获取许可。通过应用程序中的编程约定来建立信号量的正确用法。<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquire(intpermits)</span><br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。<br style="line-height:25px"> 获取给定数目的许可(如果提供了)并立即返回,将可用的许可数减去给定的量。<br style="line-height:25px"> 如果没有足够的可用许可,则在发生以下两种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的某个释放方法,当前线程是下一个被分配允许的线程并且可用许可的数目满足此请求;或者<br style="line-height:25px"> *其他某些线程中断当前线程。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"><br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待许可时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。任何原本应该分配给此线程的许可将被分配给其他试图获取许可的线程,<br style="line-height:25px"> 就好像已通过调用release()而使许可可用一样。<br style="line-height:25px"> 参数:<br style="line-height:25px"> permits-要获取的许可数<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程已被中断<br style="line-height:25px"> IllegalArgumentException-如果permits为负<br style="line-height:25px"><span style="color:#993300; line-height:25px">protectedvoid</span><span style="color:#ff6600; line-height:25px">reducePermits(intreduction)</span><br style="line-height:25px"> 根据指定的缩减量减小可用许可的数目。此方法在使用信号量来跟踪那些变为不可用资源的子类中很有用。<br style="line-height:25px"><span style="color:#000080; line-height:25px">此方法不同于acquire,在许可变为可用的过程中,它不会阻塞等待。</span><br style="line-height:25px"> 参数:<br style="line-height:25px"> reduction-要移除的许可数<br style="line-height:25px"> 抛出:<br style="line-height:25px"> IllegalArgumentException-如果reduction是负数<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:这个方法是"protected"的。关于此方法的使用请见例2<wbr style="line-height:25px"><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">例1</wbr></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticvoid</span><span style="color:#ff6600; line-height:25px">semaphoreDemo</span><span style="color:#3366ff; line-height:25px">()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try</span><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Threadt=newSemaphoreDemoThread(sem);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">t.start();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">t.interrupt();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("tisinterruped:"+t.isInterrupted());</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><span style="color:#993300; line-height:25px">catch</span><span style="color:#3366ff; line-height:25px">(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#ff6600; line-height:25px">SemaphoreDemoThread</span><span style="color:#3366ff; line-height:25px">extendsThread</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Semaphoresem=null;</span><br style="line-height:25px"><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">SemaphoreDemoThread(Semaphoresem)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.sem=sem;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">publicvoidrun()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquireUninterruptibly();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Thread.sleep(1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}catch(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.printStackTrace();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">例2</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privatestaticfinalint</span><span style="color:#0000ff; line-height:25px">MAX_AVAILABLE=3;<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">privatefinalstatic</span><span style="color:#0000ff; line-height:25px">MySemaphoresem=newMySemaphore(MAX_AVAILABLE,true);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticvoid</span><span style="color:#ff6600; line-height:25px">semaphoreDemo()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try</span><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"beforereduce");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.reducePermits(2);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterreduce");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterrealesetwo");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterrealeseanotherone");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><span style="color:#993300; line-height:25px">catch</span><span style="color:#3366ff; line-height:25px">(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">extends</span><span style="color:#3366ff; line-height:25px">Semaphore</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px">(intpermits)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(permits);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px">(intpermits,booleanfair)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(permits,fair);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px">reducePermits(intreduction)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.reducePermits(reduction);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"> 结果如下:<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:0beforereduce</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:-2afterreduce</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:0afterrealesetwo</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:1afterrealeseanotherone</span> </wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>
该线程结束后,将项返回到池中并将许可返回到该信号量,从而允许其他线程获取该项。
注意,调用acquire()时无法保持同步锁,因为这会阻止将项返回到池中。
<wbr style="line-height:25px">注意1</wbr><wbr style="line-height:25px">:"<span style="color:#000080; line-height:25px">调用acquire()时无法保持同步锁,因为这会阻止将项返回到池中</span>"因为如果调用acquire()时保持同步锁,这时如果它被阻塞了,<br style="line-height:25px"> 调putItem(Objectx)时,它又调用markAsUnused()了,而markAsUnused()需要同步锁。这时就死锁了。<br style="line-height:25px"> 信号量封装所需的同步,以限制对池的访问,这同维持该池本身一致性所需的同步是分开的。<br style="line-height:25px"><span style="color:#003366; line-height:25px">将信号量初始化为1,使得它在使用时最多只有一个可用的许可,从而可用作一个相互排斥的锁。<br style="line-height:25px"> 这通常也称为二进制信号量,因为它只能有两种状态:</span><span style="color:#000080; line-height:25px">一个可用的许可,或零个可用的许可</span><span style="color:#003366; line-height:25px">。<br style="line-height:25px"> 按此方式使用时,二进制信号量具有某种属性(与很多Lock实现不同),即可以由其他线程释放“锁”,而不是由所有者(因为信号量没有所有权的概念)。</span><br style="line-height:25px"> 在某些专门的上下文(如死锁恢复)中这会很有用。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:<wbr style="line-height:25px"><span style="color:#000080; line-height:25px">因为信号量没有所有权的概念,非二进制的信号量当然也可以由其他线程释放许可,而不一定要是所有者</span><wbr style="line-height:25px">。<br style="line-height:25px"><span style="line-height:25px; color:rgb(255,0,255)">Semaphore</span><span style="color:#003366; line-height:25px">的构造方法可选地接受一个公平参数。当设置为false时,此类不对线程获取许可的顺序做任何保证。</span><br style="line-height:25px"> 特别地,闯入是允许的,也就是说可以在已经等待的线程前为调用acquire()的线程分配一个许可,<br style="line-height:25px"> 从逻辑上说,<span style="color:#000080; line-height:25px">就是新线程将自己置于等待线程队列的头部。当公平设置为true时,信号量保证对于任何调用获取方法的线程而言,<br style="line-height:25px"> 都按照处理它们调用这些方法的顺序(即先进先出;FIFO)来选择线程、获得许可。</span><br style="line-height:25px"> 注意,<span style="color:#000080; line-height:25px">FIFO排序必然应用到这些方法内的指定内部执行点。所以,可能某个线程先于另一个线程调用了acquire,但是却在该线程之后到达排序点,并且从方法返回时也类似</span>。还要注意,<span style="color:#000080; line-height:25px">非同步的tryAcquire方法不使用公平设置,而是使用任意可用的许可</span>。<br style="line-height:25px"> 通常,应该将用于控制资源访问的信号量初始化为公平的,以确保所有线程都可访问资源。<br style="line-height:25px"> 为其他的种类的同步控制使用信号量时,非公平排序的吞吐量优势通常要比公平考虑更为重要。<br style="line-height:25px"> 此类还提供便捷的方法来同时acquire和释放多个许可。小心,在未将公平设置为true时使用这些方法会增加不确定延期的风险。<br style="line-height:25px"> 内存一致性效果:<span style="color:#000080; line-height:25px">线程中调用“释放”方法(比如release())之前的操作happen-before另一线程中紧跟在成功的“获取”方法(比如acquire())之后的操作。</span><br style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">注意1</span><span style="color:#000080; line-height:25px">:即使将公平参数设置为"true",会按照FIFO来选择线程,即先到达先被分配许可,但是先调用acquire,并不能保证该线程先到达<wbr style="line-height:25px">。</wbr></span><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">主要函数</wbr></span><wbr style="line-height:25px">:<br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquire()</span>throwsInterruptedException<wbr style="line-height:25px"><br style="line-height:25px"> 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的许可,则在发生以下两种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *某些其他线程调用此信号量的release()方法,并且当前线程是下一个要被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待许可时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程被中断<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1:</wbr></span>它可以抛出InterruptedException<wbr style="line-height:25px"><br style="line-height:25px"><wbr style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquireUninterruptibly()</span><wbr style="line-height:25px"><br style="line-height:25px"> 从此信号量中获取许可,在有可用的许可前将其阻塞。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,将可用的允许数减1。<br style="line-height:25px"> 如果没有可用的许可,则在其他某些线程调用此信号量的release()方法,并且当前线程是下一个要被分配许可的线程前,<br style="line-height:25px"> 禁止当前线程用于线程安排目的并使其处于休眠状态。<br style="line-height:25px"> 如果当前线程在等待许可时被中断,那么它将继续等待,但是与没有发生中断,其将接收允许的时间相比,为该线程分配许可的时间可能改变。<br style="line-height:25px"> 当线程确实从此方法返回后,将设置其中断状态。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:"当线程确实从此方法返回后,将设置其中断状态"<br style="line-height:25px"> 这句话不正确。我觉得acquireUninterruptibly()。如果阻塞,它仅仅是忽略对中断(即中断状态)的处理。<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">具体见例1</wbr></span><wbr style="line-height:25px">,关于Interrupted的更多内容请参见《Interrupt》<br style="line-height:25px"> publicbooleantryAcquire()<br style="line-height:25px"> 仅在调用时此信号量存在一个可用许可,才从信号量获取许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的许可,则此方法立即返回并且值为false。<br style="line-height:25px"> 即使已将此信号量设置为使用公平排序策略,但是调用tryAcquire()也将立即获取许可(如果有一个可用),<br style="line-height:25px"> 而不管当前是否有正在等待的线程。在某些情况下,此“闯入”行为可能很有用,即使它会打破公平性也如此。<br style="line-height:25px"> 如果希望遵守公平设置,则使用tryAcquire(0,TimeUnit.SECONDS),它几乎是等效的(它也检测中断)。<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;否则返回false<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:即使已将此信号量设置为使用公平排序策略,但是调用tryAcquire()也将立即获取许可(如果有一个可用),而不管当前是否有正在等待的线程。<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicboolean</span><span style="color:#ff6600; line-height:25px">tryAcquire</span>(longtimeout,<br style="line-height:25px"> TimeUnitunit)<br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的允许,则在发生以下三种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的release()方法并且当前线程是下一个被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程;或者<br style="line-height:25px"> *已超出指定的等待时间。<br style="line-height:25px"> 如果获取了许可,则返回值为true。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待获取许可的同时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 如果超出了指定的等待时间,则返回值为false。如果该时间小于等于0,则方法根本不等待。<br style="line-height:25px"> 参数:<br style="line-height:25px"> timeout-等待许可的最多时间<br style="line-height:25px"> unit-timeout参数的时间单位<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;如果获取许可前超出了等待时间,则返回false<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程是已中断的<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicboolean</span><span style="color:#ff6600; line-height:25px">tryAcquire</span>(longtimeout,<br style="line-height:25px"> TimeUnitunit)<br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 如果在给定的等待时间内,此信号量有可用的许可并且当前线程未被中断,则从此信号量获取一个许可。<br style="line-height:25px"> 获取一个许可(如果提供了一个)并立即返回,其值为true,将可用的许可数减1。<br style="line-height:25px"> 如果没有可用的允许,则在发生以下三种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的release()方法并且当前线程是下一个被分配许可的线程;或者<br style="line-height:25px"> *其他某些线程中断当前线程;或者<br style="line-height:25px"> *已超出指定的等待时间。<br style="line-height:25px"> 如果获取了许可,则返回值为true。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待获取许可的同时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。<br style="line-height:25px"> 如果超出了指定的等待时间,则返回值为false。如果该时间小于等于0,则方法根本不等待。<br style="line-height:25px"> 参数:<br style="line-height:25px"> timeout-等待许可的最多时间<br style="line-height:25px"> unit-timeout参数的时间单位<br style="line-height:25px"> 返回:<br style="line-height:25px"> 如果获取了许可,则返回true;如果获取许可前超出了等待时间,则返回false<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程是已中断的<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">release()</span><br style="line-height:25px"> 释放一个许可,将其返回给信号量。<br style="line-height:25px"> 释放一个许可,将可用的许可数增加1。如果任意线程试图获取许可,则选中一个线程并将刚刚释放的许可给予它。<br style="line-height:25px"> 然后针对线程安排目的启用(或再启用)该线程。<br style="line-height:25px"> 不要求释放许可的线程必须通过调用acquire()来获取许可。通过应用程序中的编程约定来建立信号量的正确用法。<br style="line-height:25px"><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#ff6600; line-height:25px">acquire(intpermits)</span><br style="line-height:25px"> throwsInterruptedException<br style="line-height:25px"> 从此信号量获取给定数目的许可,在提供这些许可前一直将线程阻塞,或者线程已被中断。<br style="line-height:25px"> 获取给定数目的许可(如果提供了)并立即返回,将可用的许可数减去给定的量。<br style="line-height:25px"> 如果没有足够的可用许可,则在发生以下两种情况之一前,禁止将当前线程用于线程安排目的并使其处于休眠状态:<br style="line-height:25px"> *其他某些线程调用此信号量的某个释放方法,当前线程是下一个被分配允许的线程并且可用许可的数目满足此请求;或者<br style="line-height:25px"> *其他某些线程中断当前线程。<br style="line-height:25px"> 如果当前线程:<br style="line-height:25px"><br style="line-height:25px"> *被此方法将其已中断状态设置为on;或者<br style="line-height:25px"> *在等待许可时被中断。<br style="line-height:25px"> 则抛出InterruptedException,并且清除当前线程的已中断状态。任何原本应该分配给此线程的许可将被分配给其他试图获取许可的线程,<br style="line-height:25px"> 就好像已通过调用release()而使许可可用一样。<br style="line-height:25px"> 参数:<br style="line-height:25px"> permits-要获取的许可数<br style="line-height:25px"> 抛出:<br style="line-height:25px"> InterruptedException-如果当前线程已被中断<br style="line-height:25px"> IllegalArgumentException-如果permits为负<br style="line-height:25px"><span style="color:#993300; line-height:25px">protectedvoid</span><span style="color:#ff6600; line-height:25px">reducePermits(intreduction)</span><br style="line-height:25px"> 根据指定的缩减量减小可用许可的数目。此方法在使用信号量来跟踪那些变为不可用资源的子类中很有用。<br style="line-height:25px"><span style="color:#000080; line-height:25px">此方法不同于acquire,在许可变为可用的过程中,它不会阻塞等待。</span><br style="line-height:25px"> 参数:<br style="line-height:25px"> reduction-要移除的许可数<br style="line-height:25px"> 抛出:<br style="line-height:25px"> IllegalArgumentException-如果reduction是负数<br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">注意1</wbr></span><wbr style="line-height:25px">:这个方法是"protected"的。关于此方法的使用请见例2<wbr style="line-height:25px"><br style="line-height:25px"><span style="line-height:25px"><wbr style="line-height:25px">例1</wbr></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticvoid</span><span style="color:#ff6600; line-height:25px">semaphoreDemo</span><span style="color:#3366ff; line-height:25px">()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try</span><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Threadt=newSemaphoreDemoThread(sem);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">t.start();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">t.interrupt();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("tisinterruped:"+t.isInterrupted());</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><span style="color:#993300; line-height:25px">catch</span><span style="color:#3366ff; line-height:25px">(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#ff6600; line-height:25px">SemaphoreDemoThread</span><span style="color:#3366ff; line-height:25px">extendsThread</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Semaphoresem=null;</span><br style="line-height:25px"><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">SemaphoreDemoThread(Semaphoresem)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">this.sem=sem;</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">publicvoidrun()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquireUninterruptibly();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">Thread.sleep(1);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}catch(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">e.printStackTrace();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><wbr style="line-height:25px"><span style="line-height:25px">例2</span><br style="line-height:25px"><span style="color:#0000ff; line-height:25px"></span><span style="color:#993300; line-height:25px">privatestaticfinalint</span><span style="color:#0000ff; line-height:25px">MAX_AVAILABLE=3;<br style="line-height:25px"></span><span style="color:#993300; line-height:25px">privatefinalstatic</span><span style="color:#0000ff; line-height:25px">MySemaphoresem=newMySemaphore(MAX_AVAILABLE,true);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">staticvoid</span><span style="color:#ff6600; line-height:25px">semaphoreDemo()</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">try</span><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.acquire();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"beforereduce");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.reducePermits(2);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterreduce");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterrealesetwo");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">sem.release();</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">System.out.println("availablePermits:"+sem.availablePermits()+"afterrealeseanotherone");</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><span style="color:#993300; line-height:25px">catch</span><span style="color:#3366ff; line-height:25px">(InterruptedExceptione)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#993300; line-height:25px">class</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">extends</span><span style="color:#3366ff; line-height:25px">Semaphore</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px">(intpermits)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(permits);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#ff6600; line-height:25px">MySemaphore</span><span style="color:#3366ff; line-height:25px">(intpermits,booleanfair)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super(permits,fair);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px"></span><span style="color:#993300; line-height:25px">publicvoid</span><span style="color:#3366ff; line-height:25px">reducePermits(intreduction)</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">{</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">super.reducePermits(reduction);</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">}</span><br style="line-height:25px"> 结果如下:<br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:0beforereduce</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:-2afterreduce</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:0afterrealesetwo</span><br style="line-height:25px"><span style="color:#3366ff; line-height:25px">availablePermits:1afterrealeseanotherone</span> </wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr></wbr>