java中concurrent包_java的concurrent包

最近在网上看到一个将concurrent包的系列文章,仔细读了一遍,感觉不错。

Concurrent包主要有三个package组成。java.util.concurrent:提供大部分关于并发的接口和类,如BlockingQueue,Callable,ConcurrentHashMap,ExecutorService, Semaphore等。

java.util.concurrent.atomic:提供所有原子操作的类, 如AtomicInteger, AtomicLong等;

java.util.concurrent.locks:提供锁相关的类, 如Lock, ReentrantLock, ReadWriteLock, Condition等;

CountDownLatch

CountDownLatch等待多个线程完成执行,这个类会等待多个子线程结束后才开始执行主线程的其他操作。直接上一个例子。

@Test

public void testCountDown(){

int count = 10;

final CountDownLatch l = new CountDownLatch(count);

for (int i = 0; i < count; ++i){

final int index = i;

new Thread(new Runnable() {

@Override

public void run() {

try {

Thread.currentThread().sleep(3 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("thread " + index + " has finished...");

l.countDown();

}

}).start();

}

try {

l.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("now all threads have finished");

} 这个例子中,结束语句会在所有线程结束后再执行,否则会一直await。

Atomic类

Atomic相关类是线程安全的,支持无阻塞无锁定的操作set(),get(),getAndSet(), getAndIncrement(),getAndDecrement(),getAndAdd()

@Test

public void testAtomic(){

final int loopcount = 10000;

int threadcount = 10;

final NonSafeSeq seq1 = new NonSafeSeq();

final SafeSeq seq2 = new SafeSeq();

final CountDownLatch l = new CountDownLatch(threadcount);

for(int i = 0; i < threadcount; ++i){

final int index = i;

new Thread(new Runnable() {

@Override

public void run() {

for(int j = 0; j < loopcount; ++j){

seq1.inc();

seq2.inc();

}

System.out.println("finished : " + index);

l.countDown();

}

}).start();

}

try {

l.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("both have finished....");

System.out.println("NonSafeSeq:" + seq1.get());

System.out.println("SafeSeq with atomic: " + seq2.get());

}

class NonSafeSeq{

private long count = 0;

public void inc(){

count++;

}

public long get(){

return count;

}

}

class SafeSeq{

private AtomicLong count = new AtomicLong(0);

public void inc(){

count.incrementAndGet();

}

public long get(){

return count.longValue();

}

} 输出结果如下:

both have finished....

NonSafeSeq:93212

SafeSeq with atomic: 100000 很明显看出来在原始方法中即使做了10000次相加操作也没有办法保证多线程下的一致性。使用AtomicLong进行相加可以避免这样的问题。

ReentrantLock类

之前一直是使用synchronized关键字来保证线程间的同步。concurrent包提供了ReentrantLock类,该类提供lock()和unlock()方法

1. 是更好的性能,

2. 提供同一个lock对象上不同condition的信号通知

3. 还提供lockInterruptibly这样支持响应中断的加锁过程,意思是说你试图去加锁,但是当前锁被其他线程hold住,然后你这个线程可以被中断;

这里直接上下相关lock操作的代码

class SafeSeqWithLock{

private long count = 0;

private ReentrantLock lock = new ReentrantLock();

public void inc(){

lock.lock();

try{

count++;

}

finally{

lock.unlock();

}

}

public long get() {

return count;

}

} 可以看到,这里在++操作之前先lock了,然后再执行了unlock操作。

ReadWriteLock

读锁可以有很多个锁同时上锁,只要当前没有写锁;

写锁是排他的,上了写锁,其他线程既不能上读锁,也不能上写锁;同样,需要上写锁的前提是既没有读锁,也没有写锁;

试图获得写锁的线程只有当另外一个线程将读锁释放了以后才可以获得

@Test

public void testRWLock_getw_onr(){

ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

final Lock rlock = lock.readLock();

final Lock wlock = lock.writeLock();

final CountDownLatch l = new CountDownLatch(2);

// start r thread

new Thread(new Runnable() {

@Override

public void run() {

System.out.println(new Date() + "now to get rlock");

rlock.lock();

try {

Thread.currentThread().sleep(3 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(new Date() + "now to unlock rlock");

rlock.unlock();

l.countDown();

}

}).start();

// start w thread

new Thread(new Runnable() {

@Override

public void run() {

System.out.println(new Date() + "now to get wlock");

wlock.lock();

System.out.println(new Date() + "now to unlock wlock");

wlock.unlock();

l.countDown();

}

}).start();

try {

l.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(new Date() + "finished");

}

总结一下。这里是concurrent包中常用的几个类。集中涉及了多线程,并发控制,锁的相关机制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值