ReentrantLock API

  java可重入鎖,簡單幾個小案例,測試特性。java

   1.嘗試鎖  tryLockide

package com.cn.cfang.ReentrantLock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Test02 {

    private Lock lock = new ReentrantLock();
    
    private void m1(){
        try{
            lock.lock();
            for(int i = 0; i < 10; i++){
                TimeUnit.SECONDS.sleep(1);
                System.out.println("m1() method " + i);
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    private void m2(){
        boolean isLocked = false;
        try {
            //嘗試鎖,若是已被其餘線程鎖住,沒法獲取鎖標記,則返回false
            //相反,若是獲取鎖標記,則返回true
            //isLocked = lock.tryLock();
            
            //阻塞嘗試鎖:會阻塞參數表明的時長,再去嘗試獲取鎖標記
            //若是超時未獲取,不繼續等待,直接返回false
            //阻塞嘗試鎖相似於自旋鎖。
            isLocked = lock.tryLock(11, TimeUnit.SECONDS);
            if(isLocked){
                System.out.println("method m2 synchronized");
            }else{
                System.out.println("method m2 unsynchronized");
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            if(isLocked){
                lock.unlock();
            }
        }
    }
    
    public static void main(String[] args) {
        Test02 t = new Test02();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                t.m1();
            }
        }).start();
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                t.m2();
            }
        }).start();
    }
}

  2. 可中斷測試

package com.cn.cfang.ReentrantLock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * ReentrantLock的可打斷性
 * 
 * 打斷 : 調用thread.interrupt()方法,可打斷線程阻塞狀態,拋出異常。
 * 可嘗試打斷,阻塞等待鎖。
 * 
 * 阻塞狀態 :包括普通阻塞狀態,等待隊列,鎖池隊列
 * 普通阻塞 : sleep,能夠被打斷。
 * 等待隊列 : wait方法調用,也是一種阻塞狀態,不能被打斷,只能等待notify
 * 鎖池隊列 : 沒法獲取鎖標記。不是全部的鎖池隊列都能被打斷
 *         ReentrantLock的lock獲取鎖標記的時候,若是未獲取,須要阻塞的去等待鎖標記,沒法被打斷
 *         ReentrantLock的lockInterruptibly獲取鎖標記的時候,若是未獲取,須要阻塞等待,能夠被打斷
 * 
 * @author cfang
 * 2018年5月4日 下午2:23:41
 */
public class Test03 {

    private Lock lock = new ReentrantLock();
    
    private void m1(){
        try {
            lock.lock();
            for(int i = 0; i < 5; i++){
                TimeUnit.SECONDS.sleep(1);
                System.out.println("m1() method " + i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally{
            lock.unlock();
        }
    }
    
    private void m2(){
        try {
            lock.lockInterruptibly(); //可嘗試打斷,阻塞等待鎖,能夠被其餘的線程打斷阻塞狀態
            System.out.println("m2() method");
        } catch (InterruptedException e) {
//            e.printStackTrace();
        }finally{
            //可能異常打斷,因此釋放鎖標記必須進行異常處理
            try {
                lock.unlock();
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
    
    public static void main(String[] args) {
        Test03 t = new Test03();
        
        new Thread(new Runnable() {
            @Override
            public void run() {
                t.m1();
            }
        }).start();
        
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                t.m2();
            }
        });
        t2.start();
        
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t2.interrupt(); //打斷線程休眠阻塞等待。非正常結束阻塞狀態的線程,都會拋出異常。
    }
}

  3. 公平鎖 : ReentrantLock可定義公平鎖,多個線程競爭鎖標記的時候,公平鎖會記錄等待時長,當前線程執行結束後,會優先選取等待時長最長的線程,去獲取鎖標記執行。spa

    synchronized不具備此特性。線程

 1 package com.cn.cfang.ReentrantLock;
 2 
 3 import java.util.concurrent.TimeUnit;
 4 import java.util.concurrent.locks.Lock;
 5 import java.util.concurrent.locks.ReentrantLock;
 6 
 7 public class Test04 {
 8 
 9     public static void main(String[] args) {
10         TestReentrantlock t = new TestReentrantlock();
11         new Thread(t).start();
12         new Thread(t).start();
13     }
14     
15 }
16     
17 class TestReentrantlock implements Runnable{
18     
19     private Lock lock = new ReentrantLock(true); //加參數true,表明公平鎖 
20     @Override
21     public void run() {
22         for (int i = 0; i < 5; i++) {
23             lock.lock();
24             try {
25                 System.out.println(Thread.currentThread().getName() + " get lock");
26             }finally{
27                 lock.unlock();
28             }
29         }
30     }
31 }
相關文章
相關標籤/搜索