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接口这里还介绍一个它的实现 ...
随机推荐
- Solaris10安装配置LDAP(iPlanet Directory Server )
Solaris10安装光盘自带了iPlanet Directory Server安装包,系统管理员可以利用iPlanet Directory Server在Solaris系统创建一个LDAP Serv ...
- Mybatis 内置 Java 类型别名与 typeHandlers
aliases There are many built-in type aliases for common Java types. They are all case insensitive, n ...
- eclipse利用mybatis-generator生成代码
由于mybatis是半自动的ORM框架,表到POJO的映射可以由mybatis-generator完成,映射文件也可以由它生成,下面介绍生成步骤: 1.新建maven项目:File->Other ...
- [P4782]2-SAT问题
解题关键:2-sat模板,tarjan解决. #include<iostream> #include<cstring> #include<cstdio> #incl ...
- SqlServer中把结果集放到到临时表的方法(转)
一. SELECT INTO 1. 使用select into会自动生成临时表,不需要事先创建 select * into #temp from sysobjects 01. 把存储过程结 ...
- java Swing 练习
import javax.swing.JFrame; public class Swingtest { static final int WIDTH = 500; static final int H ...
- Unity3d 脚本与C#Socket服务器传输数据
Test.cs脚本 ------------------------------------------------------------------------------------------ ...
- 通过iOS中的按钮来触发html文件中按钮所触发的函数
html文件的代码 <!DOCTYPE html> <html> <head> <title>标题</title> </head> ...
- vray学习笔记(2)vray工作流程
在bilibili上面搜索到了一个vray的教程,虽然是英语的,细节方面可能听不太懂,但可以了解整个工作流程,工作流程太重要了,先看下视频的目录: 第1节到第9节都是建模的内容. 第10节和第13节是 ...
- IP地址在mysql的存储
因为int比varchar(15)更高效,且php和mysql都有ip和int互转的函数,所以在ip地址在mysql中用int存储最优. mysql存储这个值是字段需要用int UNSIGNED.不用 ...