今天我才知道,线程池也是可以有返回值的

多线程使用,带返回值的线程池 业务需求拿到多个接口返回的信息集合,并通过判断对比整合数据,考虑可能并发比较高,所以引用线程池来完成; 可返回值的任务必须实现Callable接口。 执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。 创建一个线程池,在线程中调用其他接口来实现业务需求,并把结果返回,例子如下: // 创建一个线程池 Exe... 阅读详情

所有的线程都有一个共同的特点,那就是只管执行,我们不知道是否执行成功,也拿不到线程执行后的返回值信息,那么有没有办法获得线程执行的返回值呢?这就是今天我们要介绍的Future和Callable,以及Future的实现类FutureTask,有了Future和Callable之后,最终我们就可以知道线程池也是可以有返回值的

Future/Callable初体验

Callable用法

我们先看一个Callable的使用例子:

package com.zwx.thread.futureCallable;

import java.util.Random;
import java.util.concurrent.*;

public class TestCallable {
    public static void main(String[] args) throws Exception {
        Callable<String> callable = () -> {
            return "Hello World1";
        };

        System.out.println(callable.call());

        Callable<String> callable1 = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "Hello World2";
            }
        };
        System.out.println(callable1.call());
    }

12345678910111213141516171819202122

可以看到这个和Runnable接口非常类似,不同的是多了一个返回值。

Future用法

Future一般和Callable一起使用,用于对任务执行结果进行取消、查询是否完成、获取结果等。
下面是一个简单的用法示例:

package com.zwx.thread.futureCallable;

import java.util.concurrent.*;

public class TestFuture {
    public static void main(String[] args) throws Exception{
        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future<String> future = executorService.submit(new MyCallable());

        System.out.println("任务是否完成:" + future.isDone());
        System.out.println(future.get());//阻塞直到返回结果
        System.out.println("任务是否完成:" + future.isDone());
        System.out.println("============end============");
        
        executorService.shutdown();
    }
}

class MyCallable implements Callable{
    @Override
    public Object call() throws Exception {
        Thread.sleep(2000);
        return "Hello World";
    }
}

Callable和Future原理分析

Callable原理分析

我们先看看Callable的源码:


这个和Runnable接口一样都只有一个方法,区别就是Callable接口中的方法有返回值,且可以抛出异常,而Runnable接口没有返回值也不能抛出异常。

既然这个和Runnable这么像,那么我们是不是可以通过Callable来创建线程呢?这个问题我们放在后面回答。

Future原理分析

接下来我们再来看看Future类,Future也是一个接口,总共定义了5个方法:

package java.util.concurrent;

public interface Future<V> {
    boolean cancel(boolean mayInterruptIfRunning);//取消任务(true-表示允许取消执行中的任务)
    boolean isCancelled();//任务是否在完成前被取消
    V get() throws InterruptedException, ExecutionException;//获取返回值,会被阻塞
    V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;//在指定时间内获取返回值
}
  • cancle(boolean mayInterruptIfRunning)方法:尝试取消正在执行的任务。取消成功则返回true,取消失败则返回false,如果任务已经完成,那么一定返回false,如果任务已经开始,则如果参数设置为false,那么一定返回false,如果参数设置为true(表示允许取消进行中的任务)则会尝试去取消任务,成功则返回true,失败返回false。
  • isCancelled()方法:判断当前任务在完成前是否被取消了
  • get()方法:获取任务返回值,此方法会阻塞直到成功获取到返回值。
  • get(long timeout, TimeUnit unit) :在指定时间内阻塞等待返回值,如果达到指定时间还没获取到返回值,则返回null。

FutureTask分析

FutureTask实现了RunnableFuture接口,而RunnableFuture接口又同时继承了Runnable和Future接口,所以我们就可以利用FutureTask来进行线程的创建了。
FutureTask中提供了两个构造器:


第一个构造器的用法我们下面会有演示,第二个构造器是用的Runnable接口,并且需要传入一个结果,执行成功之后拿到的是我们传入的result,并不是线程的执行结果

如何利用FutureTask/Callable创建线程

下面就是利用FutureTask来创建线程的例子:

package com.zwx.thread.futureCallable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class TestFutureTask {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask futureTask = new FutureTask(new MyCallableTask());
        Thread t1 = new Thread(futureTask);
        t1.start();

        System.out.println(futureTask.get());
    }
}

class MyCallableTask implements Callable {
    @Override
    public Object call() throws Exception {
        return "Hello World";
    }
}

线程调用start那么最后肯定是执行的run()方法,我们看看FutureTask的run()方法:


可以看到run()方法最终调用了Callable中的call方法,并获得返回值调用set方法设置到FutureTask的成员属性outcome。


finishComletion方法其实就是去管理内部的一个简单的链表WaitNode:


这里面是如何管理的在这里我们不深入介绍,这个在旧版本jdk中用的就是AQS同步队列来实现的,所以可以看到很多地方的介绍都是说内部用的是AQS来保证线程同步,但是jdk1.8中用的就是一个简单的WaitNode来维护线程,但是原理和AQS同步队列是一致的

最后我们再看看get()方法是如何取值的:


这个方法很简单就是如果任务没完成那就阻塞,最后通过report方法拿到结果。

FutureTask状态分析

FutureTask中总共有7种状态:

  • NEW:初始化任务后的状态
  • COMPLETING:任务正常完成但是返回值还没有赋值给outcome属性。
  • NORMAL:任务正常完成且返回值已经赋值给outcome属性。
  • EXCEPTIONAL:任务出现异常且将异常信息赋值给了outcome属性(可以参见setException方法)
  • CANCELLED:调用cancle(false)方法取消NEW状态任务
  • INTERRUPTING:调用cancle(true)方法取消运行中任务,但是任务还没有中断
  • INTERRUPTED:调用cancle(true)方法取消运行中任务,且任务已经被中断。

FutureTask的状态流转可能有以下四种流转方式:

  • 1、正常完成且正常赋值:NEW -> COMPLETING -> NORMAL
  • 2、正常完成但是赋值异常:NEW -> COMPLETING -> EXCEPTIONAL
  • 3、开始执行任务之前就被取消:NEW -> CANCELLED
  • 4、开始执行任务之后被中断:NEW -> INTERRUPTING -> INTERRUPTED

线程池的submit方法和execute方法区别

上一篇我们分析线程池的时候详细分析过execute方法的执行流程了,如果想了解的可以点击这里。
在这里我们主要分析一下submit方法:


可以看到这里会调用newTaskFor方法将我们的Callable任务封装成一个FutureTask再调用execute方法执行任务,而execute方法内最终会调用runWorker方法,最终又是调用了task.run()方法,所以最终普通的Runnable任务就会调用Runnable接口的run()方法,而Callable任务最终就会调用了Callable中的call()方法,并且将返回值设置到FutureTask的outcome属性,最终我们可以通过get()方法获取到返回值。

总结

本文主要介绍了Future和Callable的用法,并且介绍了Future的实现类FutureTask的应用,最后我们介绍了如何利用Future和Callable来创建一个有返回值的线程,并且分析了线程池当中的execute和submit方法的区别,相信通过本文的学习,大家可以知道了,利用Future和Callable,线程可以有返回值,而且线程池也是可以有返回值的。

线程池的工作原理、七大参数及线程池的种类 目录 线程池的创建方式 线程池的优势 Runable和Callable接口的区别 java的几种线程池 线程池的七大参数 线程池底层工作原理 线程的拒绝策略 手写线程池 如何确定这些参数? 死锁编码及定位分析 线程池的创建方式: (1)继承Thread类;很少用,实际都是面向接口编程。 (2)实现Runable接口 ; (3)实现Callable接口(JDK>=1.5);(4)线程池创建。 线程池的优势 Runable和Callable接口... 阅读详情

相关推荐

别再说“一个有返回值一个没有”了!你真的懂 submit 和 execute 的区别吗?

submit() 的异常处理千万别忘了!一定要 future.get()。说区别时,不要只说“一个有返回值一个没有”,那太基础。最好结合业务场景说“什么时候选哪个”,让面试官觉得你是能落地的人。源码分析一定加分,不要怕说错,大胆讲逻辑。

孤芳不自赏 642

Java并发-带返回值的线程池处理流程分析

返回值存储在FutureTask类的内部变量outcome 中,设置返回值由FutureTask#run方法处理,获取返回值由FutureTask#get方法处理

1500

保姆级教程:用Python+OpenCV搞定Orbbec Gemini深度与彩色流对齐(附完整代码)

本文提供了一份详细的Orbbec Gemini深度与彩色流对齐教程,涵盖从环境配置到完整代码实现的每一步。通过解析深度流对齐原理,对比不同对齐模式,并提供工业级应用中的问题排查方法,帮助开发者快速掌握Orbbec Gemini相机的使用技巧。文章还包含进阶应用如点云生成与三维重建的实战代码。

weixin_29090917的博客 470

Java中线程池如何返回值

让你一次学会获取线程池的返回值

ProBaiXiaodi的博客 5796

AtmelStudio 7 ASF库学习笔记一:新建工程、配置时钟、下载程序和查看官方例程

由于需要学习一下atmel的atsaml 系列,使用AtmelStudio 7开发,之前主要用STM32,现在看到Atmel的库函数,其实是有些类相似的。 ASF3的库对应ST的标准库。ASF4对应ST的HAL库,Ateml Start对应STM32CubeMX。但在这里还是用ASF3来开发,因为Ateml Start还不支持我的这个芯片,而且和STM32的HAL库类似,ASF4为了好移植都是底...

yxy244的博客 8660

保姆级教程:用GEE(Google Earth Engine)复现CASA模型计算NPP,附完整数据集清单与Python代码

本文提供了一份详细的保姆级教程,指导如何使用GEE(Google Earth Engine)复现CASA模型计算NPP(净初级生产力)。教程涵盖环境准备、关键数据集获取与处理、Python代码实现全流程,以及结果验证与常见问题解决方案,帮助生态学研究者高效完成NPP计算。

weixin_28707365的博客 335

Java线程池系列(二):获取线程的返回结果

系列导航

赵昕彧 9882

采购订单定价策略 超详细

‘需求’字段里填写的是一个例程编号(例程是一段判断程序),如果我们在需求中维护了例程编号,那只有这个例程条件被满足时,这个条件表才会被系统自动读取。一部分的条件表只有在凭证项目满足一定的条件时才会被读取。 ‘排斥的’字段如果别勾中的话,那表明如果这个条件表被系统成功读取到数据后,系统将停止这个存取顺序的执行,否则,系统将继续执行下去。 注意:a、如果我们给某个条件类型设定了有效期的话,那我们必须给这个条件类型分配一个存取顺序。 b、不能给一个抬头条件分配存取顺序。 是...

竹大的博客 1万+

Java 线程池之线程返回值

前言 通常来说,开启线程能够提高程序的并发能力,而Thread 类里并没有任何方法可以获取到线程的执行结果。接下来,我们将一步步分析如何拿到线程的执行结果。 通过本篇文章,你将了解到: 1、原始方式 获取线程执行结果 2、FutureTask 获取线程执行结果 3、线程池 获取线程执行结果 1、原始方式 获取线程执行结果 public class ThreadRet { private int sum = 0; public static void main(String args[]

6191

ARM Cortex-M系列授权解析:从研发到量产的免费与付费之路

本文深入解析了ARM Cortex-M系列内核从研发到量产过程中的授权模式。研发阶段可利用ARM DesignStart等免费资源进行原型验证,但产品商业化量产则需支付授权费与版税。文章对比了采购商用MCU与自研芯片的成本差异,并探讨了RISC-V作为免费替代方案在IoT领域的应用前景与挑战,为开发者提供了清晰的选型指南。

weixin_29292431的博客 497

CSM中一些常见问题的解决方式

CSM中一些常见问题的解决方式 抖动 摄像机在每帧移动或者旋转时,会产生较严重的抖动问题。

小龙虾的博客 2132

return两个返回值_今天我才知道,线程池也是可以有返回值的

所有的线程都有一个共同的特点,那就是只管执行,我们不知道是否执行成功,也拿不到线程执行后的返回值信息,那么有没有办法获得线程执行的返回值呢?这就是今天我们要介绍的Future和Callable,以及Future的实现类FutureTask,有了Future和Callable之后,最终我们就可以知道线程池也是可以有返回值的Future/Callable初体验Callable用法我们先看一个Calla...

weixin_39928003的博客 385

搭建PX4开发系统(Ubuntu 22.04)

本文是《从零开始学 PX4 无人机开发》系列第二篇,适合开发者在 Ubuntu 系统下快速搭建 PX4 编译与仿真环境,支持 QGroundControl、Gazebo、MAVSDK 等完整工具链。

qq_15856721的博客 4222

html cgi get 获取返回值_今天我才知道,线程池也是可以有返回值的

所有的线程都有一个共同的特点,那就是只管执行,我们不知道是否执行成功,也拿不到线程执行后的返回值信息,那么有没有办法获得线程执行的返回值呢?这就是今天我们要介绍的Future和Callable,以及Future的实现类FutureTask,有了Future和Callable之后,最终我们就可以知道线程池也是可以有返回值的Future/Callable初体验Callable用法我们先看一个Calla...

weixin_35719180的博客 259

基于Lumerical FDTD的光栅耦合器宽带特性仿真与实验验证

本文详细介绍了基于Lumerical FDTD软件对光栅耦合器进行宽带特性仿真的完整流程。通过复现一个针对1310nm波段优化的经典光栅耦合器案例,文章从结构建模、光源设置、监视器布置到仿真运行与结果分析,逐步解析了如何准确模拟其耦合效率与带宽特性,并将仿真结果与实验数据进行对比验证,为硅光芯片的设计与优化提供了实用指导。

weixin_29294597的博客 513

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【并发编程系列13】Future/Callable/FutureTask:线程池也是可以有返回值的

Future/Callable/FutureTask原理分析前言Future/Callable初体验Callable用法Future用法Callable和Future原理分析Callable原理分析Future原理分析FutureTask分析如何利用FutureTask/Callable创建线程FutureTask状态分析线程池的submit方法和execute方法区别总结 前言 之前我们介绍线程的基础知识以及线程池的时候,所有的线程都有一个共同的特点,那就是只管执行,我们不知道是否执行成功,也拿不到线程执

zwx900102的博客 1401

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

线程池的理解与运用

前言: 对于线程池这一块也是比较重要的内容,这里予以记录一下。 首先是三种的使用方法 我们之前都知道的是对于 使用java的多线程而言,1.继承Thread 和 实现Ranable 等等的 现在提供了第四种使用线程的方法,使用线程池 线程池的底层的类是: ThreadPoolExecutor 49 3 举个例子来创建了一个线程池然后 进行处理 拉姆达表达式 看来明天要看一下就要了 来写一下线程池的...

weixin_44015043的博客 570

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

线程池框架_聊聊java线程池

前言没有线程池的多线程分享是没有灵魂的,由人类创造的世界正在朝着黑盒化发展,究其根源只是少部分的聪明人创造出来一些东西让大多数的懒人更加的懒罢了,但是不可否认的是这些工具都非常的好用,我个人认为今天要分享的线程池就是其中的一员。使用线程池,他就会为线程从创建到销毁的全过程保驾护航,我们要做的就只是把task进行submit或者execute即可,废话不多说了,接下来我们一点点的揭开线程池的面纱,一...

weixin_29514317的博客 128

java线程池_聊聊java线程池

前言没有线程池的多线程分享是没有灵魂的,由人类创造的世界正在朝着黑盒化发展,究其根源只是少部分的聪明人创造出来一些东西让大多数的懒人更加的懒罢了,但是不可否认的是这些工具都非常的好用,我个人认为今天要分享的线程池就是其中的一员。使用线程池,他就会为线程从创建到销毁的全过程保驾护航,我们要做的就只是把task进行submit或者execute即可,废话不多说了,接下来我们一点点的揭开线程池的面纱,一...

weixin_39712016的博客 85

今天来看看高并发中的ForkJoinPool的使用

我们可以先看一下线程池的继承关系,顶层的Executor接口,提供了一个execute()方法,我们常用的ExecutorService接口也继承自Executor接口,其中定义了一些额外的方法,下面呢就是AbstractExecutorService类,在这个类中实现了三个submit方法,而创建线程池的ThreadPoolExecutor类就继承自AbstractExecutorService,而同时ForkJoinPool也继承了AbstractExecutorService,具体关系可以看下图。

z1ztai的博客 1005

线程池学习笔记(4)——submit和execute方法区别与联系

看过源码的同学会发现我们线程池提交任务除了submit方法外,在ThreadPoolExecutor类里还有excute方法,一样可以提交任务,那么这两个方法有什么区别?我们应该怎么选择用哪个方法?我看网上也有很多帖子,看了一些,大多写的不够深入,看了之后就是知其然而不知其所以然,所以今天决定自己翻翻源码,一探究竟,直接看源码 首先,我们查看源码里方法定义,很明显能发现2个区别: 1、...

jinfengloveIT的博客 838

多线程高并发学习之线程池

临近过年,我又开始放纵自己了,托更好几天,今天中午12点半刚回到老家,带着我的狗子,今天是过年之前最后一个集,大街上可热闹了,我中午吃了饭去外边逛了逛,逛了一圈,想起我已经鸽了好几天了,于是我良心发现,赶紧回到家,打开电脑,开始肝文章。 废话不多说,今天来跟大家讲讲线程池从入门到入土 在讲线程池之前先说几个相关的类 线程池入门前需了解的类 Executor Executor是一个接口,只有一个execute方法叫执行,也就是说你可以指定一个线程去执行他的run方法 ExecutorService Execu

qq_38991247的博客 168

多线程高并发学习之线程池从入门到入土

多线程高并发学习之线程池从入门到入土 ​ 临近过年,我又开始放纵自己了,托更好几天,今天中午12点半刚回到老家,带着我的狗子,今天是过年之前最后一个集,大街上可热闹了,我中午吃了饭去外边逛了逛,逛了一圈,想起我已经鸽了好几天了,于是我良心发现,赶紧回到家,打开电脑,开始肝文章。 废话不多说,今天来跟大家讲讲线程池从入门到入土 在讲线程池之前先说几个相关的类 线程池入门前需了解的类 Executor Executor是一个接口,只有一个execute方法叫执行,也就是说你可以指定一个线程去执行他的run方法

qq_42280920的博客 233

为什么java线程池的submit既可以提交runnable也可以提交callable?

前言 大家好,今天鸡翅老哥继续带大家深入了解多线程,我们都知道多线程有两种实现方式,一种是实现runnable接口,一种是实现callable接口。那么线程池的submit提交方式,两种都可以作为参数传递。要知道submit是当需要返回值的情况下才使用,runnable是没有返回值,那么submit为什么可以接收两种呢,我们继续往下看。 submit方法解析 先看下submit的方法,来确定,确实可以提交两种方式。 我们定义一个线程池,来执行两个方法,第一种没有返回值,线程池会自动找到runna

经典鸡翅 2732

金九银十:线程、多线程,线程池面试题十连问!

点击上方关注 “终端研发部”设为“星标”,和你一起掌握更多数据库知识大家好我是小于哥啊,最近的面试中,关于线程、多线程,线程池相关的面试题还是挺多的。今天我们来分享一下最近常问线程,多线程...

这个时代,作为程序员可能要学习小程序 992

java 单例 线程阻塞_Java Util Concurrent并发编程(三)阻塞队列和线程池

之前简单的介绍了一些并发的基础知识。还用实际代码证实了常用集合类的不安全。另外也简单说了下Concurrent中的常用的几个辅助类。今天这篇文章主要是简单介绍下与Lock同等级的读写锁还有队列。ReadWriteLock读写锁是个接口,我们先去手册中简单看下这个介绍:ReadWriteLock简单介绍其实这个读不加锁写加锁的设计在好多地方都有涉及。比如数据库读写分离。还有缓存是写入的时候更新。读的...

weixin_39931923的博客 219
上一篇: Java泛型最全归纳,你知道的和不知道的都能找到
下一篇: 我告诉你一个 AtomicInteger 的大秘密
JavaShark
博客等级 码龄4年 184粉丝 438原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值