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接口这里还介绍一个它的实现 ...
随机推荐
- Word中调整编号和文字的间距
鼠标放在节文字上,不用选择该级别的所有节点,直接在某一节上右键-段落-制表位-默认制表位-设置1字符或其它.完成后该级别所有节的格式都自动调整,不用一个个调整. 但是设置其它段落格式还是需要在菜单上选 ...
- 如何解决SSH登录Solaris主机速度慢的问题
SSH登录速度慢可能有多种原因. 1. 与DNS有关 缺省情况下,当客户端用SSH登录solaris服务器时,服务器会试图反向解析客户端的IP 地址(即把IP地址解析成机器名).如果Solaris系统 ...
- jdbcTemplate学习(一)
概述 Spring JDBC抽象框架core包提供了JDBC模板类,其中JdbcTemplate是core包的核心类,所以其他模板类都是基于它封装完成的,JDBC模板类是第一种工作模式. JdbcTe ...
- C语言学习笔记--动态库和静态库的使用
1.C语言中的链接器 (1)每个 C 语言源文件被编译后生成目标文件,这些目标文件最终要被链接在一起生成可执行文件. (2)链接器的主要作用是把各个模块之间相互引用的部分处理好,使得各个模块之间能够正 ...
- Yahoo浮沉录
Yahoo这一路曾经出过很多好技术 然而,任何人如果只是把 Yahoo 当作一家缺乏聚焦的企业来看也许忽视了公司内部的那些创新—偶尔甚至还有一些很好的产品创意.就拿搜索来说吧,我们说的不是付费搜索,而 ...
- c++primer-p101.ex3.24
要求使用迭代器 读入一组整数并把它们存入一个vector对象 1. 将相邻每对整数和输出 2. 先输出第一个和最后一个数的和,然后是第二个和倒数第二个...等等 自己写的: #include<i ...
- C run-time函数总览
Argument Access(参数访问):变长参数列表.这个模块提供了三个宏:va_arg.va_end和va_start,用来实现变长参数列表的访问. Buffer Manipulation(内存 ...
- ES6中的Set与Map数据结构
本文实例讲述了ES6学习笔记之Set和Map数据结构.分享给大家供大家参考,具体如下: 一.Set ES6提供了新的数据结构Set.类似于数组,只不过其成员值都是唯一的,没有重复的值. Set本身是一 ...
- IO流对文件的读取操作
/*1. 在当前项目的根目录下有一个名为“info.txt”的文件,里面存放的内容如下(可手动创建录入,不需要使用IO流): 2. 利用IO流的知识读取info.txt文件的内容, 在控制台上打印大写 ...
- Halcon将裁剪后的图像还原为原始大小
************************************************************* * Halcon将裁剪后的图像还原为原始大小 * Author: LiGua ...