Java几种并发类总结:
ReentrantLock(重入锁):基于AQS(同步器)队列和Condition队列完成,将等待线程与阻塞线程分开
示例代码:
package lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import org.junit.Test;
public class LockTest {
public static void main(String[] args){
final ReentrantLock reentrantLock = new ReentrantLock();
final Condition condition = reentrantLock.newCondition();
//新建线程1并启动,进入AQS等待队列
new Thread(new Runnable(){
public void run() {
//线程1调用方法,如果拿到锁,从AQS等待队列中移除,未拿到则保持在AQS等待队列中
reentrantLock.lock();
System.out.println(Thread.currentThread().getName()+"拿到锁了");
System.out.println(Thread.currentThread().getName()+"等待信号");
try {
//加入Condition等待队列,等待信号同时释放锁
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"拿到信号");
reentrantLock.unlock();
}
},"线程1").start();
//新建线程2并启动,进入AQS等待队列
new Thread(new Runnable(){
public void run() {
//线程2拿到锁,从AQS队列中移除
reentrantLock.lock();
System.out.println(Thread.currentThread().getName()+"拿到锁了");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"发出信号");
//取出Condition等待队列中的线程1,加入AQS等待队列
condition.signalAll();
//释放锁
reentrantLock.unlock();
}
},"线程2").start();
}
}
CountDownLatch(线程计数):主线程和若干个子线程同时进行时(场景),初始化计数器子线程个数,每个线程执行完毕后计数器减一,当等于零时,阻塞的主线程恢复执行
CylicBarrier(线程等待):每个线程类中维护一个CylicBarrier对象,当每一个线程到达barrrier.await()方法时被阻塞,当所有线程到达改位置后,执行CylicBarrier对象内初始化的线程(有则执行) ,继续执行其他线程到结束
Semaphore(信号量):多个线程获取少量资源,在一个线程只能操作一个资源的前提下,控制资源的许可和释放
BlockingQueue(阻塞队列):维护一个队列,当队列为空时,无法获取或删除队列中的对象,当队列满时,无法插入一个对象
示例代码:
package lock;
import java.util.concurrent.ArrayBlockingQueue;
/*
* 使用阻塞队列实现生产者消费者模型
*/
public class BockingQueue {
public static void main(String[] args){
//初始化阻塞队列的长度
final int queueSize = 10;
//初始化阻塞队列
final ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<Integer>(queueSize);
new Thread(new Runnable(){
public void run() {
int i = 0;
while(true){
try {
blockingQueue.put(1);
System.out.println(Thread.currentThread().getName()+"添加了一个元素,队列剩余空间"+(queueSize-blockingQueue.size()));
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"线程2").start();
new Thread(new Runnable(){
public void run() {
while(true){
try {
System.out.println(Thread.currentThread().getName()+"取走了元素,还剩"+blockingQueue.size()+"个元素");
blockingQueue.take();
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
},"线程1").start();
}
}