1. 程式人生 > 實用技巧 >Current併發包(四) - lock

Current併發包(四) - lock

LOCK


lock概述

非靜態同步方法鎖是this

靜態同步方法鎖的鎖物件是當前類的位元組碼

在JDK1.5中,提供了Lock介面

通過lock方法加鎖, 通過該unlock方法解鎖

鎖的公平和非公平策略

在非公平策略下,執行緒的執行次數並不均等,甚至會出現較大的差距

在公平策略下,執行緒的執行次數應該是均等的

從效率角度考慮,非公平的效率會相對較高

synchronized使用的是非公平策略

Lock預設是非公平策略

LockDemo.java
package com.wiscom.lock;
​
public class LockDemo {
​
    static
int i = 0; public static void main(String[] args) throws InterruptedException { // true 為公平策略 false為非公平策略 Lock l = new ReentrantLock(true); new Thread(new Add(l)).start(); new Thread(new Add(l)).start(); ​ Thread.sleep(2000); System.out.println(i); } ​ } ​
class Add implements Runnable { private Lock l; ​ public Add(Lock l) { this.l = l; } ​ @Override public void run() { // 加鎖 l.lock(); for (int i = 0; i < 10000; i++) { LockDemo.i++; } // 解鎖 l.unlock(); } ​ } ​

ReadWriteLock -- 讀寫鎖

ReadWriteLock lock = new ReentrantReadWriteLock();

加讀鎖

lock.readLock();

解讀鎖

lock.readLock().unlock;

其他鎖

CountDownLatch

閉鎖/執行緒遞減鎖

對執行緒進行計數,在計數歸零之前,執行緒會被阻塞

CountDownLatchDemo.java
package com.wiscom.lock;
​
public class CountDownLatchDemo {
​
    public static void main(String[] args) throws InterruptedException {
​
        CountDownLatch cdl = new CountDownLatch(6);
        new Thread(new Teacher(cdl)).start();
        new Thread(new Student(cdl)).start();
        new Thread(new Student(cdl)).start();
        new Thread(new Student(cdl)).start();
        new Thread(new Student(cdl)).start();
        new Thread(new Student(cdl)).start();
        // 在計數歸零之前,需要讓主函式所線上程先陷入阻塞
        // 當計數歸零之後,自動的放開阻塞
        cdl.await();
        System.out.println("開始考試~~~");
    }
}
class Teacher implements Runnable {
​
    private CountDownLatch cdl;
​
    public Teacher(CountDownLatch cdl) {
        this.cdl = cdl;
    }
​
    @Override
    public void run() {
        try {
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println("考官到達考場~~~");
            // 減少1個計數
            cdl.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
​
}
​
class Student implements Runnable {
​
    private CountDownLatch cdl;
​
    public Student(CountDownLatch cdl) {
        this.cdl = cdl;
    }
​
    @Override
    public void run() {
        try {
            Thread.sleep((long) (Math.random() * 10000));
            System.out.println("考生到達考場~~~");
            cdl.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
​
}