java并发常用类
来源:互联网 发布:pop3默认端口号 编辑:程序博客网 时间:2024/06/14 16:57
- 阻塞队列BlockingQueue
- CallableFuture和FutureTask
- 使用CallableFuture获得执行的结果
- 使用CallableFutureTask获得执行的结果
- CountDownLatch用法
- CyclicBarrier用法
- Semaphore用法
阻塞队列BlockingQueue
从阻塞这个词可以看出,在某些情况下对阻塞队列的访问可能会造成阻塞。被阻塞的情况主要有如下两种:
- 当队列满了的时候禁止入队列操作
- 当队列空了的时候禁止出队列操作
用法:阻塞队列主要用在生产者/消费者的场景,下面这幅图展示了一个线程生产、一个线程消费的场景
package com.koma.demo;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.BlockingQueue;/** * @author koma * @version 2017年12月1日 上午10:32:19 */public class BlockingQueueTest { public static void main(String[] args) { BlockingQueue<String> queue=new ArrayBlockingQueue<>(2); Consumer consumer=new Consumer(queue); Producer producer=new Producer(queue); consumer.start(); producer.start(); } static class Consumer extends Thread{ BlockingQueue<String> queue; public Consumer(BlockingQueue<String> queue){ this.queue=queue; } @Override public void run() { while(true){ try { String s=queue.take(); System.out.println("消费者消费: "+s); } catch (InterruptedException e) { e.printStackTrace(); } } } } static class Producer extends Thread{ BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue){ this.queue=queue; } @Override public void run() { while(true){ try { for(int i=0;i<5;i++){ queue.put(System.currentTimeMillis()+" "+i); System.out.println("生产者生产!"+i); } Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
Callable,Future和FutureTask
Callable:有返回值的Runnable。
Future:接口是用来获取异步计算结果的,说白了就是对具体的Runnable或者Callable对象任务执行的结果进行获取(get()),取消(cancel()),判断是否完成等操作。
FutureTask:除了实现了Future接口外还实现了Runnable接口,因此FutureTask也可以直接提交给Executor执行
具体有哪些方法请查看api文档。
使用Callable+Future获得执行的结果
package com.koma.demo;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/** * @author koma * @version 2017年12月1日 上午11:06:11 */public class FutureTest { public static void main(String[] args) { ExecutorService service=Executors.newSingleThreadExecutor(); Future<Integer> future=service.submit(new CallableDome()); try { int i=future.get();//会阻塞等待结果返回 System.out.println("callble 返回的结果是: "+i); service.shutdown(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } static class CallableDome implements Callable<Integer>{ @Override public Integer call() throws Exception { return 1; } }}
使用Callable+FutureTask获得执行的结果
package com.koma.demo;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.FutureTask;/** * @author koma * @version 2017年12月1日 上午10:57:24 */public class FutureTaskTest { public static void main(String[] args) { ExecutorService service=Executors.newSingleThreadExecutor(); FutureTask<Integer> task=new FutureTask<>(new CallableDome()); service.submit(task); try { int i=task.get(); //会阻塞等待结果返回 System.out.println("callble 返回的结果是: "+i); service.shutdown(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } static class CallableDome implements Callable<Integer>{ @Override public Integer call() throws Exception { return 1; } }}
CountDownLatch用法
情景:比如有一个任务A,它要等待其他几个线程执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。
package com.koma.demo;import java.util.concurrent.CountDownLatch;/** * @author koma * @version 2017年12月1日 下午1:57:58 */public class CountDownLatchTest { public static void main(String[] args) { CountDownLatch latch = new CountDownLatch(2);//初始化count值 new Thread(new Runnable() { @Override public void run() { System.out.println("子线程" + Thread.currentThread().getName() + "开始运行"); try { Thread.sleep(3000);// 模拟任务运行 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程" + Thread.currentThread().getName() + "结束运行"); latch.countDown();//将count值减1 } }).start(); new Thread(new Runnable() { @Override public void run() { System.out.println("子线程" + Thread.currentThread().getName() + "开始运行"); try { Thread.sleep(3000);// 模拟任务运行 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("子线程" + Thread.currentThread().getName() + "结束运行"); latch.countDown(); //将count值减1 } }).start(); System.out.println("主线程执行任务,但是得等待所有的子线程执行完,才能运行!"); try { latch.await(); //调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("2个子线程已经执行完毕"); System.out.println("继续执行主线程"); }}
CyclicBarrier用法
字面意思回环栅栏,通过它可以实现让一组线程等待至某个状态之后再全部同时执行。叫做回环是因为当所有等待线程都被释放以后,CyclicBarrier可以被重用。我们暂且把这个状态就叫做barrier,当调用await()方法之后,线程就处于barrier了。
package com.koma.demo;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * @author koma * @version 2017年12月1日 下午2:27:52 */public class CyclicBarrierTest { public static void main(String[] args) { int n=3; CyclicBarrier barrier=new CyclicBarrier(n); for(int i=0;i<n;i++){ Demo demo=new Demo(barrier); demo.start(); } } static class Demo extends Thread{ private CyclicBarrier cyclicBarrier; public Demo(CyclicBarrier cyclicBarrier){ this.cyclicBarrier=cyclicBarrier; } @Override public void run() { System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据..."); try { Thread.sleep(2000);//以睡眠来模拟写入数据操作 System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕"); cyclicBarrier.await(); //线程在这等待了,所有线程都运行到这了,才会继续往下运行 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println("所有线程写入完毕,继续处理其他任务..."); } }}
CyclicBarrier构造还可以指定一个Runable参数
package com.koma.demo;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * @author koma * @version 2017年12月1日 下午2:27:52 */public class CyclicBarrierTest { public static void main(String[] args) { int n=3; CyclicBarrier barrier=new CyclicBarrier(n,new Runnable() { @Override public void run() { // 选择其中一个线程运行 System.out.println("线程名字: "+Thread.currentThread().getName()); } }); for(int i=0;i<n;i++){ Demo demo=new Demo(barrier); demo.start(); } } static class Demo extends Thread{ private CyclicBarrier cyclicBarrier; public Demo(CyclicBarrier cyclicBarrier){ this.cyclicBarrier=cyclicBarrier; } @Override public void run() { System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据..."); try { Thread.sleep(2000);//以睡眠来模拟写入数据操作 System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕"); cyclicBarrier.await(); //线程在这等待了,所有线程都运行到这了,才会继续往下运行 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println("所有线程写入完毕,继续处理其他任务..."); } }}
CyclicBarrier可以重用
package com.koma.demo;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * @author koma * @version 2017年12月1日 下午2:27:52 */public class CyclicBarrierTest { public static void main(String[] args) { int n=3; CyclicBarrier barrier=new CyclicBarrier(n); for(int i=0;i<n;i++){ Demo demo=new Demo(barrier); demo.start(); } try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } for(int i=0;i<n;i++){ Demo demo=new Demo(barrier); demo.start(); } } static class Demo extends Thread{ private CyclicBarrier cyclicBarrier; public Demo(CyclicBarrier cyclicBarrier){ this.cyclicBarrier=cyclicBarrier; } @Override public void run() { System.out.println("线程"+Thread.currentThread().getName()+"正在写入数据..."); try { Thread.sleep(1000);//以睡眠来模拟写入数据操作 System.out.println("线程"+Thread.currentThread().getName()+"写入数据完毕,等待其他线程写入完毕"); cyclicBarrier.await(); //线程在这等待了,所有线程都运行到这了,才会继续往下运行 } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println("所有线程写入完毕,继续处理其他任务..."); } }}
Semaphore用法
Semaphore翻译成字面意思为 信号量,Semaphore可以控同时访问的线程个数,通过 acquire() 获取一个许可,如果没有就等待,而 release() 释放一个许可。
用Semaphore来控制set的容量大小
package com.koma.demo;import java.util.HashSet;import java.util.Set;import java.util.concurrent.Semaphore;/** * @author koma * @version 2017年12月1日 下午3:43:06 */public class SemaphoreTest { private Set<Integer> set; private Semaphore semaphore; public SemaphoreTest(int n) { this.set = new HashSet<>(); this.semaphore = new Semaphore(n); } public boolean add(Integer s) { // 获得一个许可 try { semaphore.acquire(); } catch (InterruptedException e) { e.printStackTrace(); } boolean was = false; try { was = set.add(s); return was; } finally { // 如果添加失败,一定要释放许可 if (!was) { semaphore.release(); } } } public boolean remove(Integer s) { boolean was = set.remove(s); if (was) { // 如果移除成功了,释放许可 semaphore.release(); } return was; } public static void main(String[] args) { // set容纳的元素不可能大于3 SemaphoreTest test=new SemaphoreTest(3); new Thread(){ @Override public void run() { while(true){ for(int i=0;i<5;i++){ test.add(i); // 添加元素 System.out.println(Thread.currentThread().getName()+" set size: "+test.set.size()); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }.start(); new Thread(){ @Override public void run() { while(true){ for(int i=0;i<5;i++){ test.remove(i); // 移除元素 System.out.println(Thread.currentThread().getName()+" set size: "+test.set.size()); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }.start(); }}
阅读全文
0 0
- java 常用并发类
- java并发常用类
- JAVA并发-并发编程常用类
- JAVA 并发类(一) 常用的并发类
- java并发编程 之 常用并发类库使用举例
- 关于Java并发的常用类回顾
- Java并发中常用同步工具类
- Java并发包中常用类
- java常用并发工具介绍
- Java 并发编程(四)常用同步工具类
- Java并发多线程常用包、类和接口
- java并发编程中常用的工具类 Executor
- java常用并发类的使用与替换
- Java并发编程之常用概念
- Java常用并发容器总结(一)
- Java常用并发容器总结(三)
- Java常用并发容器总结(四)
- Java常用并发容器(concurrent包)
- UGUI中CustomFont字体使用与制作
- Java 对称加密
- 有道云PC版网络错误解决方案
- Pandas数据结构-DataFrame
- Java字符串操作
- java并发常用类
- Linux 文件之inode理解
- Spring事务管理的核心接口
- How to craw the Info of BiliBIli with python
- ArrayList和LinkedList的几种循环遍历方式及性能对比分析
- 剑指offer第28题(数组中出现次数超过一半的数字)
- postman设置alexa
- rnn和lstm
- Azure 虚拟机代理概述