国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

詳解Java多線程編程中LockSupport類的線程阻塞用法

2019-11-26 14:04:27
字體:
來源:轉載
供稿:網友

LockSupport是用來創建鎖和其他同步類的基本線程阻塞原語。
LockSupport中的park() 和 unpark() 的作用分別是阻塞線程和解除阻塞線程,而且park()和unpark()不會遇到“Thread.suspend 和 Thread.resume所可能引發的死鎖”問題。
因為park() 和 unpark()有許可的存在;調用 park() 的線程和另一個試圖將其 unpark() 的線程之間的競爭將保持活性。

基本用法
LockSupport 很類似于二元信號量(只有1個許可證可供使用),如果這個許可還沒有被占用,當前線程獲取許可并繼 續 執行;如果許可已經被占用,當前線 程阻塞,等待獲取許可。

public static void main(String[] args){   LockSupport.park();   System.out.println("block.");}

運行該代碼,可以發現主線程一直處于阻塞狀態。因為 許可默認是被占用的 ,調用park()時獲取不到許可,所以進入阻塞狀態。

如下代碼:先釋放許可,再獲取許可,主線程能夠正常終止。LockSupport許可的獲取和釋放,一般來說是對應的,如果多次unpark,只有一次park也不會出現什么問題,結果是許可處于可用狀態。

public static void main(String[] args){   Thread thread = Thread.currentThread();   LockSupport.unpark(thread);//釋放許可   LockSupport.park();// 獲取許可   System.out.println("b");}

LockSupport是可不重入 的,如果一個線程連續2次調用 LockSupport .park(),那么該線程一定會一直阻塞下去。

public static void main(String[] args) throws Exception{ Thread thread = Thread.currentThread();  LockSupport.unpark(thread);  System.out.println("a"); LockSupport.park(); System.out.println("b"); LockSupport.park(); System.out.println("c");}

這段代碼打印出a和b,不會打印c,因為第二次調用park的時候,線程無法獲取許可出現死鎖。

下面我們來看下LockSupport對應中斷的響應性

public static void t2() throws Exception{ Thread t = new Thread(new Runnable() {  private int count = 0;  @Override  public void run()  {   long start = System.currentTimeMillis();   long end = 0;   while ((end - start) <= 1000)   {    count++;    end = System.currentTimeMillis();   }   System.out.println("after 1 second.count=" + count);  //等待或許許可   LockSupport.park();   System.out.println("thread over." + Thread.currentThread().isInterrupted());  } }); t.start(); Thread.sleep(2000); // 中斷線程 t.interrupt();  System.out.println("main over");}

最終線程會打印出thread over.true。這說明 線程如果因為調用park而阻塞的話,能夠響應中斷請求(中斷狀態被設置成true),但是不會拋出InterruptedException 。

LockSupport函數列表

// 返回提供給最近一次尚未解除阻塞的 park 方法調用的 blocker 對象,如果該調用不受阻塞,則返回 null。static Object getBlocker(Thread t)// 為了線程調度,禁用當前線程,除非許可可用。static void park()// 為了線程調度,在許可可用之前禁用當前線程。static void park(Object blocker)// 為了線程調度禁用當前線程,最多等待指定的等待時間,除非許可可用。static void parkNanos(long nanos)// 為了線程調度,在許可可用前禁用當前線程,并最多等待指定的等待時間。static void parkNanos(Object blocker, long nanos)// 為了線程調度,在指定的時限前禁用當前線程,除非許可可用。static void parkUntil(long deadline)// 為了線程調度,在指定的時限前禁用當前線程,除非許可可用。static void parkUntil(Object blocker, long deadline)// 如果給定線程的許可尚不可用,則使其可用。static void unpark(Thread thread)


LockSupport示例
對比下面的“示例1”和“示例2”可以更清晰的了解LockSupport的用法。
示例1

public class WaitTest1 {  public static void main(String[] args) {    ThreadA ta = new ThreadA("ta");    synchronized(ta) { // 通過synchronized(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 (InterruptedException e) {        e.printStackTrace();      }    }  }  static class ThreadA extends Thread{    public ThreadA(String name) {      super(name);    }    public void run() {      synchronized (this) { // 通過synchronized(this)獲取“當前對象的同步鎖”        System.out.println(Thread.currentThread().getName()+" wakup others");        notify();  // 喚醒“當前對象上的等待線程”      }    }  }}

示例2

import 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);    }  }}

運行結果:

main start tamain blockta wakup othersmain continue

說明:park和wait的區別。wait讓線程阻塞前,必須通過synchronized獲取同步鎖。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 青岛市| 博爱县| 青岛市| 天门市| 黄浦区| 奎屯市| 葫芦岛市| 垫江县| 包头市| 仙游县| 磐安县| 宜黄县| 库尔勒市| 资阳市| 常山县| 洞口县| 上林县| 穆棱市| 武陟县| 承德县| 陆丰市| 高要市| 沂源县| 鄂伦春自治旗| 本溪| 平顺县| 华蓥市| 抚松县| 定结县| 吉安市| 大英县| 上饶县| 理塘县| 札达县| 延安市| 盐亭县| 长乐市| 拜城县| 威海市| 建昌县| 芦山县|