天天看点

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();

}

}

}