并发工具类
CountDownLatch
CountDownLatch允许一个或多个线程等待其他线程完成操作,相当于计数器
代码实例
staticCountDownLatch c = new CountDownLatch(2);
public static void main(String[] args)throws InterruptedException{
new Thread(
new Runnable){
@Override
public void run(){
System.out.println(1);
c.countDown();
System.out.println(2);
c.countDown();
}
}
).start();
c.await();
System.out.println("3");
}
CyclicBarrier
让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障取消,被拦截的线程继续运行,相当于限定人数放行的屏障门
相对于CountDownLatch,CyclicBarrier的计数器可以使用reset()重置,而CountDownLatch的计数器只能使用一次;
另外,getNumberWaiting() 可以获得阻塞的线程数量,isBroken()可以了解是否被中断;
代码实例
staticCyclicBarrier c = new CyclicBarrier(2);
public static void main(String[] args){
new Thread(
new Runnable(){
@Override
public void run(){
try{
c.await();
}catch(Exception e){ }
System.out.println(1);
}
}
).start();
try{
c.await();
}catch(Exception e){ }
System.out.println(2);
}
Semaphore
Semophore用来控制同时访问特定资源,通过协调各个线程,保证合理使用公共资源,相当于限流器
代码实例
private static final int THREAD_COUNT = 30;
private static ExecutorServicethreadPool = Executors.newFixedThreadPool(THREAD_COUNT);
pirvate static Semaphore s = new Semaphore(10);
public static void main(String[] args){
for(inti = 0; i<THREAD_COUNT; i++){
threadPool.execute(
@Override
public void run(){
try{
s.acquire();
System.out.println("save data");
s.release();
}catch(InterruptedException e){ }
}
);
}
threadPool.shutdown();
}
Exchanger
Exchanger用于线程间协作,进行线程间数据交换;
提供一个同步点,在同步点两个线程可以交换彼此数据;
代码实例
private static final Exchanger<String> exchanger = new Exchanger<String>();
private static ExecutorServicethreadPool = Executors.newFieldThreadPool(2);
public static void main(String[] args){
threadPool.execute(
new Runnable(){
@Override
public void run(){
try{
String A = "银行流水A";
exchanger.exchange(A);
}catch(InterruptedException e){ }
}
}
);
threadPool.execute(
new Runnable(){
@Override
public void run(){
try{
String B = "银行流水B";
String A = exchanger.exchange(B);
System.out.println("A和B是否一致:" + A.equals(B));
}catch(InterruptedException e){ }
}
}
);
threadPool.shutdown();
}
线程池
好处
- 降低资源消耗,不用重复创建销毁线程;
- 提高相应速度,立即执行,无须创建;
- 提高线程的可管理性;
操作
创建线程池:
new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, milliseconds, runnableTaskQueue, handler);
execute提交任务:
threadPool.execute(
new Runnable(){
@Override
public void run(){
//TODO
}
}
);
submit提交任务:
Future<Object> future = executor.submit(harReturnValuetask);
try{
Object s = future.get();
}catch(Exception e){
}finally{
executor.shutdown();
}
小结
并发工具类提供了并发流程控制的手段,而线程池则提高了线程的管理,优化了性能;
总之,他们都在不同业务场景为我们提供线程的控制和管理