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接口这里还介绍一个它的实现 ...
随机推荐
- Python函数(三)-局部变量
全局变量 全局变量在函数中能直接访问 # -*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" name = 'John' def te ...
- 如何使用安装光盘为本机创建yum repository
在CentOS 6上可以使用系统安装光盘为本机创建yum repository,创建过程如下. 创建光盘mount点 [root@centos62 ~]# mkdir /media/CentOS mo ...
- docker 笔记(3)第一个dockerfile
#vim Dockerfile FROM ubuntu RUN apt-get update && apt-get install -y vim #docker build -t ub ...
- 0016_练习题d2
__author__ = 'qq593' #!/usr/bin/env python #-*- coding:utf-8 -*- #元素分类,有如下值集合[11,22,33,44,55,66,77,8 ...
- Niginx +Tomcat 集群搭建
1 安装niginx服务器,然后启动,访问localhost;出现欢迎界面证明niginx启动成功: 如上图的目录是nginx1.1的目录结构: 2 之后下载tomcat,然后赋值一份,总共两个tom ...
- 如何选择RDBMS关系型数据库和Nosql非关系型数据库?
RDBMS关系型数据库和Nosql非关系型数据库区别: 一.RDBMS是关系型数据库模式: 1.二维模式,由行列组成. 2.非常强调事务原子性,例如用户提出一个请求,DB完整的去执行,如果报错就全部回 ...
- [patl2-020]功夫传人
解题关键:dfs的简单应用,需要注意类型double与int #include<cstdio> #include<cstring> #include<algorithm& ...
- css知多少(5)——选择器(转)
css知多少(5)——选择器 1. 引言 从本节开始,就进入本系列的第二个部分——css和html的结合——说白了就是选择器. CSS中定义了样式,如何将这些样式设置到相应的html节点上?就不得 ...
- C++ 成员函数前和函数后加const修饰符区别
博客转载自: https://www.iteblog.com/archives/214.html 分析以下一段程序,阐述成员函数后缀const 和 成员函数前const 的作用 #include< ...
- 机器人自主移动的秘密:SLAM与路径规划有什么关系?(三)
博客转载自:https://www.leiphone.com/news/201612/lvDXqY82OGNqEiyl.html 雷锋网(公众号:雷锋网)按:本文作者SLAMTEC(思岚科技公号sla ...