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
  • 实际上形成一个阻塞队列
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章