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 队列:LinkedBlockingQueueArrayBlockingQueue(长度固定)

  (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-其他组件的更多相关文章

  1. 高并发第十二弹:并发容器J.U.C -- Executor组件FutureTask、ForkJoin

    从本章开始就要说 Executor 的东西了.本次讲的是一个很常用的FutureTask,和一个不是那么常用的ForkJoin,我们现在就来介绍吧 引言 大部分时候创建线程的2种方式,一种是直接继承T ...

  2. Java并发编程 (八) J.U.C组件拓展

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.J.U.C-FutureTask-1 FutureTask组件,该组件是JUC中的.但该组件不是 A ...

  3. Java GUI 基础组件

    1.JLabel  标签 构造函数: JLabel() JLabel(String text) JLabel(String text,int align)     //第二个参数设置文本的对齐方式,常 ...

  4. Java基础学习总结 -- 图形用户界面GUI

    虽然目前Java算不上前端开发的主力,但是作为Java入门基础的一部分,学习Java的GUI编程还是有必要的,而且可以做出一些小且有趣的图形程序来提高学习热情.本篇学习总结均为一个Beginner的笔 ...

  5. java提高篇---Vector

    对于List接口这里还介绍一个它的实现类Vector,Vector 类可以实现可增长的对象数组. 一.Vector简介 Vector可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问 ...

  6. 关于DPM(Deformable Part Model)算法中模型结构的解释

    关于可变部件模型的描写叙述在作者[2010 PAMI]Object Detection with Discriminatively Trained Part Based Models的论文中已经有说明 ...

  7. jsp js java

    Java技术 J a v a是一种 简单易用. 完全面向对象. 具有平台无关性且 安全可靠的主要面向I n t e r n e t的开发工具. 自从1 9 9 5年正式问世以来,J a v a的快速发 ...

  8. BATJ面试必会之并发篇

    一.线程状态转换 新建(New) 可运行(Runnable) 阻塞(Blocking) 无限期等待(Waiting) 限期等待(Timed Waiting) 死亡(Terminated) 二.使用线程 ...

  9. 集合之Vector

    在java提高篇(二一)—–ArrayList.java提高篇(二二)—LinkedList,详细讲解了ArrayList.linkedList的原理和实现过程,对于List接口这里还介绍一个它的实现 ...

随机推荐

  1. JCTF 2014(Reverse)

    小菜一碟: 点击下载附件 下载的附件没有后缀,用c32打开看看 是apk文件,用Smali2JavaUI打开 程序把输入框的字符串反转,然后进行MD5加密,最后进行base64编码,与NzU2ZDJm ...

  2. numpy.percentile

    http://docs.scipy.org/doc/numpy/reference/generated/numpy.percentile.html numpy.percentile(a, q, axi ...

  3. Android 媒体编解码器(转)

    媒体编解码器 MediaCodec类是用来为低级别的媒体编码和解码的媒体编解码器提供访问.您可以实例化一个MediaCodec类通过调用createEncoderByType()方法来进行对媒体文件进 ...

  4. resin容器更改JDK

    更改resin的jdk版本,找到resin的配置文件:Resin\contrib\init.resin文件,找到 JAVA_HOME=@JAVA_HOME@ RESIN_HOME=@resin_hom ...

  5. 安装vs2012以后 sql2008不能使用解决办法

    出现的错误 (1) 打开控制面板,找到卸载程序,把”MicrosoftSQL Server 2013(2012) Express LocalDB”卸载掉,然后打开SQL Server 配置管理器,就会 ...

  6. windows下单机版的伪分布式solrCloud环境搭建Tomcat+solr+zookeeper

    原文出自:http://sbp810050504.blog.51cto.com/2799422/1408322           按照该方法,伪分布式solr部署成功                 ...

  7. springBoot 案例

    一.工具 JDK1.7 Eclipse Maven 这里Eclipse集成Maven的这一步就省了! 二.编码 新建Maven Project 命名为:SpringBootDemo 选项如图 2.修改 ...

  8. final 子类禁止重写

    <?php //子类中编写和父类中完全一样的函数,是对父类中的函数进行重写 class BaseClass{ public function test() { echo "BaseCl ...

  9. JS 中的数组遍历方式效率比较

    JS数组遍历,基本就是for,forin,foreach,forof,map等等一些方法,以下介绍几种本文分析用到的数组遍历方式以及进行性能分析对比 第一种:普通for循环 代码如下: ; j < ...

  10. 机器学习初探(手写数字识别)matlab读取数据集

    手写数字识别是机器学习里面的一个经典问题,今天就这一段时间学习的机器学习,花一个下午茶的时间,试试机器学习. 首先数据库是在MNIST(http://yann.lecun.com/exdb/mnist ...