Lock ReadWriteLock CyclicBarrier Semaphore【Java 併發】

Lock

Lock是Java 5以後引入的新的API

  • ReentrantLock
    • 可保證順序、可查詢阻塞Thread list、可設置超時、查詢持有lock的Thread
    • 注意必須 主動unlock,退出Thread不會清空lock
  • CyclicBarrier
    • 在await阻塞
    • 設置阻塞 的線程數
    • 從0遞增 數值
    • 可以reset 數值
    • 到達最大值 放行,await()的Thread
    • 可break barrier,喚醒全部線程
  • CountDownLatch (比CyclicBarrier少太多方法)
    • 在await阻塞
    • 設置 阻塞的最大數值
    • 從最大值遞減
    • 數值爲0放行,await()的Thread
    • 不可reset 數值
  • Semaphore
    • 設置可用資源的最大值
    • 可增 可減數值
  • Exchanger
    • 在exchange時阻塞,等另一個Thread調用exchange,交換Object

方法

  • lock()
  • lockInterruptibly()
    • interrupt狀態無法獲得鎖
    • 等待lock時,如果interrupt則拋異常退出
  • tryLock()
    • never block
  • tryLock(long timeout, TimeUnit timeUnit)
  • unlock()

實現類ReentrantLock

  • 可以設置timeout
  • 可以保證順序
  • 可以查詢wait的thread 列表
Lock lock = new ReentrantLock();

lock.lock();

//critical section

lock.unlock();

ReadWriteLock

多線程讀(沒線程寫)、一個線程寫

interface

public interface ReadWriteLock {
    /**
     * Returns the lock used for reading.
     *
     * @return the lock used for reading
     */
    Lock readLock();

    /**
     * Returns the lock used for writing.
     *
     * @return the lock used for writing
     */
    Lock writeLock();
}

實現類 ReentrantReadWriteLock

ReadWriteLock readWriteLock = new ReentrantReadWriteLock();


readWriteLock.readLock().lock();

    // multiple readers can enter this section
    // if not locked for writing, and not writers waiting
    // to lock for writing.

readWriteLock.readLock().unlock();


readWriteLock.writeLock().lock();

    // only one writer can enter this section,
    // and only if no threads are currently reading.

readWriteLock.writeLock().unlock();

CyclicBarrier

等到0通行,設置阻塞線程數量

  • 設置一個 阻斷器,設置阻斷線程的數量
  • 當阻斷到 指定的數量是放行
  • 可以設置放行時運行的Runnable
Runnable barrier1Action = new Runnable() {
    public void run() {
        System.out.println("BarrierAction 1 executed ");
    }
};
Runnable barrier2Action = new Runnable() {
    public void run() {
        System.out.println("BarrierAction 2 executed ");
    }
};

CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action);
CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action);

CyclicBarrierRunnable barrierRunnable1 =
        new CyclicBarrierRunnable(barrier1, barrier2);

CyclicBarrierRunnable barrierRunnable2 =
        new CyclicBarrierRunnable(barrier1, barrier2);

new Thread(barrierRunnable1).start();
new Thread(barrierRunnable2).start();

public class CyclicBarrierRunnable implements ++Runnable++{

    CyclicBarrier barrier1 = null;
    CyclicBarrier barrier2 = null;

    public CyclicBarrierRunnable(
            CyclicBarrier barrier1,
            CyclicBarrier barrier2) {

        this.barrier1 = barrier1;
        this.barrier2 = barrier2;
    }

    public void run() {
        try {
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() +
                                " waiting at barrier 1");
            this.barrier1.await();

            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() +
                                " waiting at barrier 2");
            this.barrier2.await();

            System.out.println(Thread.currentThread().getName() +
                                " done!");

        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

CountDownLatch

倒計時鎖

  • 設置初始值
  • latch.await();
  • latch.countDown(); 到0時放行

Semaphore

允許進入 關鍵區域的 最大線程數

Semaphore semaphore = new Semaphore(1);

//critical section
semaphore.acquire();

...

semaphore.release();

2. 兩個線程通信

  • 例如在 insertData到list後,acquire調用
  • 在take object from list前,調用release
  • 實際上形成一個阻塞隊列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章