Locksupportは、ロックやその他の同期クラスを作成するために使用される基本的なスレッドブロックプリミティブです。
locksupportのpark()とunpark()の機能は、それぞれスレッドとブロックを解除することであり、park()とupark()は、「thread.suspendおよびthread.resumeによって引き起こされるデッドロック」という問題に遭遇しません。
Park()とunpark()には権限があるためです。スレッドコールパーク()とupark()を試みる別のスレッドとの競合は、アクティブのままです。
基本的な使用法
Locksupportは、バイナリセマフォに非常に似ています(1つのライセンスのみが利用可能です)。このライセンスが占有されていない場合、現在のスレッドはライセンスを取得し、実行を継続します。ライセンスが占有されている場合、現在のスレッドがブロックされ、ライセンスの取得を待っています。
public static void main(string [] args){locksupport.park(); System.out.println( "block。");}コードを実行すると、メインスレッドが常にブロックされていることがわかります。ライセンスはデフォルトで占有されているため、Park()を呼び出すときにライセンスを取得できないため、ブロッキング状態になります。
次のコード:最初にライセンスをリリースし、次にライセンスを取得すると、メインスレッドは正常に終了できます。 Locksupportライセンスの取得とリリースは、一般に対応しています。複数回駐車していれば、一度だけ駐車しても問題はありません。その結果、ライセンスは利用可能な状態にあります。
public static void main(string [] args){thread = thread.currentthread(); locksupport.unpark(thread); //ライセンスlocksupport.park(); //ライセンスシステムを取得します。locksupportはリエントラントではありません。スレッドがlocksupport .park()を連続して2回呼び出すと、スレッドは間違いなくブロックされます。
public static void main(string [] args)スロー例外{thread = thread.currentthread(); locksupport.unpark(スレッド); system.out.println( "a"); locksupport.park(); System.out.println( "b"); locksupport.park(); System.out.println( "c");}このコードはaとbを印刷しますが、cを印刷しません。なぜなら、パークを2回目に呼び出すときにスレッドが許可を取得できないためです。
Locksupportの対応する割り込みの応答を見てみましょう
public static void t2()throws exception {thread t = new runnable(){private int count = 0; @override public void run(){long start = system.currenttimemillis(); long end = 0; second.count = " + count); //許可を許可locksupport.park(); system.out.println(" thread over。 " + thread.currentthread()。is interrupted());}}); t.start(); Thread.Sleep(2000); //割り込みスレッドT.Interrupt(); system.out.println( "main over");}スレッドはスレッドオーバーを印刷します。つまり、スレッドが呼び出しパークのためにブロックされた場合、割り込み要求に応答できます(割り込みステータスはtrueに設定されています)が、ターゲットエクセプトをスローしないことを意味します。
locksupport関数リスト
//最新のブロックされていないParkメソッドコールに提供されたブロッカーオブジェクトを返し、呼び出しがブロックされていない場合はnullを返します。 Static Object GetBlocker(Thread T)//スレッドスケジューリングの場合、ライセンスが利用可能でない限り、現在のスレッドを無効にします。 static void park()//スレッドスケジューリングの場合、ライセンスが利用可能になる前に現在のスレッドを無効にします。静的ボイドパーク(オブジェクトブロッカー)//スレッドスケジューリングの場合、ライセンスが利用できない限り、指定された待機時間を最大で待ちます。 Static void Parknanos(long nanos)//スレッドスケジューリングの場合、ライセンスが利用可能になる前に現在のスレッドを無効にし、最大で指定された待機時間を待ちます。静的void parknanos(オブジェクトブロッカー、ロングナノ)//スレッドスケジューリングの場合、ライセンスが利用できない限り、指定された時間制限の前に現在のスレッドが無効になります。静的void parkuntil(長期締め切り)//スレッドスケジューリングの場合、ライセンスが利用できない限り、指定された時間制限の前に現在のスレッドが無効になります。 Static void Parkuntil(オブジェクトブロッカー、長い締め切り)//特定のスレッドのライセンスがまだ利用できない場合は、利用可能にします。静的void pourark(スレッドスレッド)
locksupportの例
以下の「例1」と「例2」を比較すると、Locksupportの使用についてより明確に理解することができます。
例1
public class waittest1 {public static void main(string [] args){threada ta = new swercha( "ta");同期(ta){//同期(ta)try {system.out.println(thread.currentthread()。getName()+"start ta")を介して「オブジェクトの同期ロック」を取得します。 ta.start(); system.out.println(thread.currentthread()。getname()+"block"); //メインスレッドはta.wait()を待っています。 system.out.println(thread.currentthread()。getname()+"continue"); } catch(arturnedexception e){e.printstacktrace(); }}} static class threada extends thread {public threada(string name){super(name); } public void run(){synchronized(this){//同期(this)system.out.println(thread.currentthread()。 notify(); //目を覚ます「現在のオブジェクトの待機スレッド」}}}}例2
java.util.concurrent.locks.locksupport; public class locksupporttest1 {private static thread mainthread; public static void main(string [] args){threada ta = new threada( "ta"); //メインスレッドMainThread = thread.CurrentThread()を取得します。 system.out.println(thread.currentthread()。getname()+"start ta"); ta.start(); system.out.println(thread.currentthread()。getname()+"block"); //メインスレッドはlocksupport.park(mainthread)をブロックします。 system.out.println(thread.currentthread()。getname()+"continue"); } static class threada extends thread {public threada(string name){super(name); } public void run(){system.out.println(thread.currentthread()。getname()+"wakup others"); //「メインスレッド」locksupport.unpark(mainthread)を起動します。 }}}実行結果:
メインスタートTamain blockta wakup othersmain継続
説明:公園と待機の違い。待機する前に、スレッドをブロックする前に、同期ロックを同期して取得する必要があります。