J.U.C-其他组件
J.U.C-其他组件
FutureTask
介绍Callable时我们知道它可以有返回值,返回值通过Future进行封装。FutrueTask实现了RunnableFuture接口,该接口继承了Runnable和Future接口,这使得FutureTask既可以当做一个任务执行,也可以有返回值。
FutureTask<T>implements RunnableFuture<t>
interface RunnableFuture <T>extends Runnable,Future<t>
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class FutureTaskExemple {
public static void main(String[]args)throws InterruptedException, ExecutionException {
FutureTask<Integer> futureTask=new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int result=0;
for(int i=0;i<100;i++){
result=result+i;
Thread.sleep(10);
}
return result;
}
});
Thread computeThread=new Thread(futureTask);
computeThread.start();
Thread otherThread=new Thread(()->{
System.out.println("other Thread is running");
try{
Thread.sleep(100);
}catch (Exception e){
e.printStackTrace();
}
});
otherThread.start();
System.out.println(futureTask.get());
}
}
FutureTask 可用于异步获取执行结果或取消执行任务的场景。当一个计算任务需要执行很长时间,那么就可以用 FutureTask 来封装这个任务,主线程在完成自己的任务之后再去获取结果。
BlockingQueue
java.util.concurrent.BlockingQueue接口有以下阻塞队列实现。
(1)FIFO 队列:LinkedBlockingQueue,ArrayBlockingQueue(长度固定)
(2)优先队列:PriorityBlockingQueue
提供了阻塞的take()方法和put()方法:如果队列为空take()将阻塞,知道队列中有内容。如果队列满的话,put()就会阻塞,直到队列中有空的位置。
使用BlockingQueue实现生产者消费者问题
package ConcurrentExemple;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class BlockingQueueExemple {
public static BlockingQueue<String>queue= new ArrayBlockingQueue<>(5);
public static class Consumer extends Thread{
@Override
public void run(){
try {
String product=queue.take();
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"comsume..");
}
}
public static class Producer extends Thread{
@Override
public void run(){
try {
queue.put("product");
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"produce..");
}
}
public static void main(String[]args){
for(int i=0;i<2;i++){
Producer producer=new Producer();
producer.start();
}
for(int i=0;i<5;i++){
Consumer consumer=new Consumer();
consumer.start();
}
for(int i=0;i<3;i++){
Producer producer=new Producer();
producer.start();
}
}
}
Thread-1produce..
Thread-7produce..
Thread-5comsume..
Thread-4comsume..
Thread-2comsume..
Thread-6comsume..
Thread-3comsume..
Thread-8produce..
Thread-0produce..
Thread-9produce..
ForkJoin
主要用于并行计算中,与MapReduce原理类似,都是把大的计算任务拆分成多个小的任务并行计算。
package ConcurrentExemple;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
public class ForkJoinExemple {
public static class ForkExemple extends RecursiveTask<Integer>{
private final int threshold=5;
private int first;
private int last;
public ForkExemple(int first,int last){
this.first=first;
this.last=last;
}
@Override
public Integer compute(){
int result=0;
if(last-first<threshold){
for(int i=first;i<last;i++){
result=result+i;
}
}else{
int mid=(first+last)/2;
ForkExemple leftExemple=new ForkExemple(first,mid);
ForkExemple rigtExemple=new ForkExemple(mid+1,last);
leftExemple.fork();
rigtExemple.fork();
result=leftExemple.join()+rigtExemple.join();
}
return result;
}
}
public static void main(String[]args)throws ExecutionException ,InterruptedException{
ForkExemple forkExemple=new ForkExemple(1,10000);
ForkJoinPool forkJoinPool=new ForkJoinPool();
Future result=forkJoinPool.submit(forkExemple);
System.out.println(result.get());
}
}
ForkJoin 使用 ForkJoinPool 来启动,它是一个特殊的线程池,线程数量取决于 CPU 核数。
public class ForkJoinPool extends AbstractExecutorService
ForkJoinPool 实现了工作窃取算法来提高 CPU 的利用率。每个线程都维护了一个双端队列,用来存储需要执行的任务。工作窃取算法允许空闲的线程从其它线程的双端队列中窃取一个任务来执行。窃取的任务必须是最晚的任务,避免和队列所属线程发生竞争。Thread2从 Thread1 的队列中拿出最晚的 Task1 任务,Thread1 会拿出 Task2 来执行,这样就避免发生竞争。但是如果队列中只有一个任务时还是会发生竞争。
J.U.C-其他组件的更多相关文章
- 高并发第十二弹:并发容器J.U.C -- Executor组件FutureTask、ForkJoin
从本章开始就要说 Executor 的东西了.本次讲的是一个很常用的FutureTask,和一个不是那么常用的ForkJoin,我们现在就来介绍吧 引言 大部分时候创建线程的2种方式,一种是直接继承T ...
- Java并发编程 (八) J.U.C组件拓展
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 一.J.U.C-FutureTask-1 FutureTask组件,该组件是JUC中的.但该组件不是 A ...
- Java GUI 基础组件
1.JLabel 标签 构造函数: JLabel() JLabel(String text) JLabel(String text,int align) //第二个参数设置文本的对齐方式,常 ...
- Java基础学习总结 -- 图形用户界面GUI
虽然目前Java算不上前端开发的主力,但是作为Java入门基础的一部分,学习Java的GUI编程还是有必要的,而且可以做出一些小且有趣的图形程序来提高学习热情.本篇学习总结均为一个Beginner的笔 ...
- java提高篇---Vector
对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组. 一.Vector简介 Vector可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问 ...
- 关于DPM(Deformable Part Model)算法中模型结构的解释
关于可变部件模型的描写叙述在作者[2010 PAMI]Object Detection with Discriminatively Trained Part Based Models的论文中已经有说明 ...
- jsp js java
Java技术 J a v a是一种 简单易用. 完全面向对象. 具有平台无关性且 安全可靠的主要面向I n t e r n e t的开发工具. 自从1 9 9 5年正式问世以来,J a v a的快速发 ...
- BATJ面试必会之并发篇
一.线程状态转换 新建(New) 可运行(Runnable) 阻塞(Blocking) 无限期等待(Waiting) 限期等待(Timed Waiting) 死亡(Terminated) 二.使用线程 ...
- 集合之Vector
在java提高篇(二一)—–ArrayList.java提高篇(二二)—LinkedList,详细讲解了ArrayList.linkedList的原理和实现过程,对于List接口这里还介绍一个它的实现 ...
随机推荐
- DVWA平台v1.9-Command Injection
命令拼接: &:简单的拼接,第一条命令和第二条命令间没有什么制约关系 &&:第一条命令执行成功了,才会执行第二条命令 |:第一条命令的输出作为第二条命令的输入 ||:第一条命令 ...
- 2015.12.14 MDI(多文档窗口结构)设置基本解决,折腾一天,部分解决存在已久的问题。但效果仍不如临时航线的MDI窗体结构。
创建从一个窗口弹出多个子窗口的结构叫MDI窗体结构 如果不按MDI结构管理,最简单的做法是: 在窗体A上添加菜单或按钮,在菜单或按钮事件中添加弹出B窗体代码: B b = new B(); b.sho ...
- debian7 安装VMware Tools
前提:需要安装gcc.kernel 1. apt-get install gcc 2. apt-get install kernel 问题描述: 安装时如果提示更换介质 :请把标有 " de ...
- Solaris10技巧
如何查看UFS文件系统创建命令 root@ofs0accmcc01 # mkfs -m /dev/md/rdsk/d100 mkfs -F ufs -o nsect=128,ntrack=48,bsi ...
- C语言学习笔记--数组参数和指针参数
1. 数组参数退化为指针的意义 (1)C 语言中只会以值拷贝的方式传递参数,当向函数传递数组时,将整个数组拷贝一份传入函数导致执行效率低下,C 语言以高效作是最初的设计目标,所以这种方法是不可取的. ...
- DAY4-函数进阶
目录: 一.迭代器 二.生成器 三.面向过程编程 四.三元表达式.列表推导式.生成器表达式 五.第归与二分法 六.匿名函数 七.内置函数 练习 一.迭代器 一.迭代的概念 #迭代器即迭代的工具,那什么 ...
- 通过Excel导入Mysql 超过65535条数据的办法
1.截取 65534条数据,进行分sheet,然后1个sheet导入一张表,最后进行整合! 2.采用TXT导入方式,TXT的导入暂时没发现限制的数据条数,下午用TXT导入74万条数据成功 3.如果遇到 ...
- 给Activity切换过程添加动画效果
首先,在资源文件中定义一些动画效果 例如: <scale android:duration="@android:integer/config_mediumAnimTime" ...
- C++ 私有构造函数的作用
很多情况下要求当前的程序中只有一个object.例如一个程序只有一个和数据库的连接,只有一个鼠标的object.通常我们都将构造函数的声明置于public区段,假如我们将 其放入private区段中会 ...
- Angular22 HttpClient的使用
1 HttpClient介绍 HttpClient时Http的演进,注意:Http在@angular/http中,而HttpClient在@angular/common/http中: 使用前需要在模块 ...