天天看點

java concurrent 包_java的concurrent包簡介

java的concurrent包簡介

java的concurrent包中的鎖lock;工具類:CyclicBarrier、semaphore、CountDownLatch;集合:blockingquue、concurrentMap;原子量:aotmic。先從下面的圖開始,介紹下concurrent包的用法。

java concurrent 包_java的concurrent包簡介

1、lock類

總結幾點現在知道的synchronized的異同,基本也就是個認知階段,并不能說明真實的原理資訊。以後有時間在詳細的查閱官方資料:

synchronized:

1、JVM實作

2、可以通過工具監控

3、自動釋放

4、在等待的的時候什麼都不能幹,隻有等待喚醒(jvm喚醒、打斷)

lock:

1、代碼實作、無法監控。釋放在finally裡面

2、擷取:可以明确知道結果。當然,也就可以做等待、或者直接做其他操作

3、釋放:以任何順序擷取和釋放多個鎖、釋放方式和偏向鎖類似

3、讀寫分離鎖分離

lock的實作和偏向鎖很類似,一個特點靈活,非常靈活。當然操作起來也更加困難,不過相信随着Oracle持續的釋放黑科技優化jvm,synchronized性能越來越高。

lock的使用:

public interface Lock {

//擷取鎖。如果鎖不可用,出于線程排程目的,将禁用目前線程,并且在獲得鎖之前,該線程将一直處于休眠狀态。

void lock();

//如果目前線程未被中斷,則擷取鎖

void lockInterruptibly() throws InterruptedException;

//僅在調用時鎖為空閑狀态才擷取該鎖。如果鎖可用,則擷取鎖,并立即傳回值 true。如果鎖不可用,則此方法将立即傳回值 false。

boolean tryLock();

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

void unlock();

Condition newCondition();

}

其中lock的标準用法:如果拿不到鎖就在隊列中等待

Lock l = ...;

l.lock();

try {

// access the resource protected by this lock

} finally {

l.unlock();

}

tryLock的用法:如果沒有擷取鎖,可以直接做其他的用處

Lock lock = ...;

if (lock.tryLock()) {

try {

// manipulate protected state

} finally {

lock.unlock();

}

} else {

// perform alternative actions

}

lockInterruptibly:擷取一個帶有中斷處理的鎖。例如:線程A擷取了鎖,則不能中斷。線程B會一直循環,然後自旋不端擷取鎖,或者查詢是否有中斷指令。在AbstractQueuedSynchronizer源碼中,doAcquireInterruptibly(int arg)方法可以看出,是通過抛出異常來終端擷取鎖,在使用的時候需要用try。

public void testInterrupted() throws InterruptedException {

lock.lockInterruptibly();

try{

//TODO:

}finally{

lock.unlock();

}

例子:lock

public class lockTest implements Runnable {

private Lock lock;

public lockTest(Lock lock) {

this.lock = lock;

}

@Override

public void run() {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin");

lock.lock();

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over");

lock.unlock();

}

}

public static void main(String[] args) {

Lock lock = new ReentrantLock();

// ExecutorService es = Executors.newCachedThreadPool();

for (int i = 0; i 

new Thread(new lockTest(lock)).start();

;

}

// es.shutdown();

}

}

tryLock例子

public class TryLock implements Runnable {

private Lock lock;

public TryLock(Lock lock) {

this.lock = lock;

}

@Override

public void run() {

if (lock.tryLock()) {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin");

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over");

lock.unlock();

}

} else {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is not acquire");

}

}

public static void main(String[] args) {

Lock lock = new ReentrantLock();

TryLock trylock = new TryLock(lock);

new Thread(trylock).start();

new Thread(trylock).start();

}

}

lockInterrupte:如果目前線程未被中斷,則擷取鎖。

public class LockInterrupt implements Runnable {

private Lock lock;

public LockInterrupt(Lock lock) {

this.lock = lock;

}

private void testInterrupt() {

try {

lock.lockInterruptibly();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is begin");

// Thread.sleep(5000);// 睡眠阻塞、會被打斷

//

for (;;) {

}

} catch (InterruptedException e1) {

e1.printStackTrace();

} finally {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is over");

lock.unlock();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " is release");

}

}

@Override

public void run() {

this.testInterrupt();

}

public static void main(String[] args) {

try {

Lock lock = new ReentrantLock();

LockInterrupt li = new LockInterrupt(lock);

Thread t1 = new Thread(li, "t1");

Thread t2 = new Thread(li, "t2");

t1.start();

t2.start();

Thread.sleep(500);

t1.interrupt();

// t2.interrupt();// 會将t1的sleep直接打斷、然後t2

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

讀寫鎖ReentrantReadWriteLock:讀鎖可以多個線程一起使用。寫鎖隻能線程獨享,這時候還會阻塞其它讀鎖、寫鎖

public class WritReadTest {

private ReentrantReadWriteLock rrwl;

public WritReadTest(ReentrantReadWriteLock lock) {

this.rrwl = lock;

}

public void read() {

try {

rrwl.readLock().lock();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is begin");

Thread.sleep(5000);// 睡眠阻塞、會被打斷

} catch (InterruptedException e1) {

e1.printStackTrace();

} finally {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is over");

rrwl.readLock().unlock();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " readlock is release");

}

}

public void write() {

try {

rrwl.writeLock().lock();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is begin");

Thread.sleep(5000);// 睡眠阻塞、會被打斷

} catch (InterruptedException e1) {

e1.printStackTrace();

} finally {

System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is over");

rrwl.writeLock().unlock();

System.out.println("Thread Name: " + Thread.currentThread().getName() + " write is release");

}

}

public static void main(String[] args) {

ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();

WritReadTest wrt = new WritReadTest(rrwl);

new Thread(new ReadTest(wrt)).start();

new Thread(new WriteTest(wrt)).start();

}

}

class ReadTest implements Runnable {

public WritReadTest wrt;

public ReadTest(WritReadTest wrt) {

this.wrt = wrt;

}

@Override

public void run() {

// wrt.read();

wrt.write();

}

}

class WriteTest implements Runnable {

private WritReadTest wrt;

public WriteTest(WritReadTest wrt) {

this.wrt = wrt;

}

@Override

public void run() {

wrt.write();

// wrt.read();

}

}

condition:條件。代替Object的監視方法(wait、notify、notifyAll)。直接通過代碼将線程放入一個等待隊列,然後等待其它線程喚醒。

class BoundedBuffer {   final Lock lock = new ReentrantLock();

final Condition notFull  = lock.newCondition();

final Condition notEmpty = lock.newCondition();

final Object[] items = new Object[100];

int putptr, takeptr, count;

public void put(Object x) throws InterruptedException {     lock.lock();

try {

while (count == items.length)

notFull.await();

items[putptr] = x;

if (++putptr == items.length) putptr = 0;

++count;       notEmpty.signal();

} finally {

lock.unlock();

}

}

public Object take() throws InterruptedException {     lock.lock();

try {

while (count == 0)

notEmpty.await();

Object x = items[takeptr];

if (++takeptr == items.length) takeptr = 0;

--count;       notFull.signal();

return x;     } finally {

lock.unlock();

}

}

}