激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 詳解Java多線程編程中LockSupport類的線程阻塞用法

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

2020-05-27 11:18skywangkw JAVA教程

LockSupport類提供了park()和unpark()兩個方法來實現線程的阻塞和喚醒,下面我們就來詳解Java多線程編程中LockSupport類的線程阻塞用法:

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

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

?
1
2
3
4
5
public static void main(String[] args)
{
   LockSupport.park();
   System.out.println("block.");
}

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
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對應中斷的響應性

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
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函數列表

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 返回提供給最近一次尚未解除阻塞的 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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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);
    }
  }
}

運行結果:

?
1
2
3
4
main start ta
main block
ta wakup others
main continue

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91热久久免费频精品黑人99 | 亚洲人成电影在线 | 欧美日韩在线免费观看 | 久久久久久久久久亚洲精品 | 97干在线| 国产成人av免费看 | 国产噜噜噜噜噜久久久久久久久 | 狠狠久久伊人中文字幕 | 亚洲欧美日韩久久精品第一区 | 欧美激情精品久久久久久黑人 | 久久精品中文字幕一区二区 | av噜噜噜噜 | 中文字幕极速在线观看 | 91看片成人 | 日本久久综合网 | 最新在线中文字幕 | 伦一区二区三区中文字幕v亚洲 | 国产欧美亚洲精品a | 欧美在线观看视频一区 | av免费入口| 国产精品伦视频看免费三 | 精品无码久久久久久国产 | 欧美一区二区黄 | 一区二区三区欧美在线观看 | 欧美精品一区二区三区四区 | 男女做性免费网站 | 久久久久国产一区二区三区不卡 | 欧美电影在线观看 | 中文字幕在线播放不卡 | 狠狠久久伊人中文字幕 | 一级黄色性感片 | 一级毛片电影网 | 最新欧美精品一区二区三区 | 一区二区三区无码高清视频 | 男女隐私免费视频 | 久久久www成人免费毛片 | 国产欧美日韩久久久 | 成人wxx视频免费 | 欧美日韩手机在线观看 | 12av毛片| 麻豆一二区 |