Java高并发,创建线程的新方式Callable接口
我们已经知道创建线程的方式有1.继承thread类。2.实现Runnable接口
接下来讲创建线程的新方式Callable接口,首先对比一下Runnable接口和Callable接口的区别:
首先创建两个资源类:分别是实现了Runnable接口和实现了Callable接口:
//Runnable接口
class MyThreadRunnable implements Runnable { @Override
public void run() { }
} //Callable
class MyThreadCallable implements Callable<Integer> { @Override
public Integer call() throws Exception {
System.out.println("******come in here");
return 1024;
}
}
我们可以看到Callable存在泛型,以及返回值,这是对原来的老技术的增强,因为存在了返回值,提高了线程的细粒度。
接着我们看看Runnable创建线程的方式:
//Runnable
MyThreadRunnable myThread1=new MyThreadRunnable();
Thread t1=new Thread(myThread1);
但是通过该方式我们利用Callable来创建线程,却报错了,这是为什么 呢?

原因:Thread并不存在Callable的构造器!
如何创建Callable线程
首先查看API,看Runable接口:




过程如下:

我们可以看到的是,这个构造器需要的参数就是Callable接口的实现类。
所以,我们创建线程的方式如下:
public class CallableDemo {
public static void main(String[] args) {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(futureTask.get());// 1024 通过get方法来获取返回值
}
}
get方法具有阻塞性
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
System.out.println(Thread.currentThread().getName()+"***计算完成");
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}

然后调转依一下主线程与futureTask线程执行的顺序:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
System.out.println(Thread.currentThread().getName()+"***计算完成");
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}

往往futureTask里面的get方法会被阻塞, 所以一般情况下我们先让main线程执行完毕防止由于等待futureTask而耗时。
futureTask的单一性
新增一个线程B:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
// MyThreadCallable myThread = new MyThreadCallable();
FutureTask futureTask = new FutureTask(new MyThreadCallable());
new Thread(futureTask, "A").start();
new Thread(futureTask, "B").start();
System.out.println(Thread.currentThread().getName() + "***计算完成");
System.out.println(futureTask.get());// 1024 通过get方式来获取返回值 该方法会阻塞!
}
}
//Callable
class MyThreadCallable implements Callable<Integer> {
@Override
public Integer call() throws Exception {
System.out.println("******come in here");
Thread.sleep(5000);
return 1024;
}
}

只执行了一次,因为一个futureTask,不管几个线程调用,调用的都是同一个futureTask对象!而且Runnable接口就不一样了:
public class CallableDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
MyThreadRunnable t = new MyThreadRunnable();
Thread thread = new Thread(t);
new Thread(thread).run();
new Thread(thread).run();
}
}
//Runnable接口
class MyThreadRunnable implements Runnable {
@Override
public void run() {
System.out.println("******come in here");
}
}
以上..
Java高并发,创建线程的新方式Callable接口的更多相关文章
- 创建线程之三:实现Callable接口
通过Callable和Future创建线程 i. 创建Callable接口的实现类,并实现call方法,该call方法将作为线程执行体,并且有返回值,可以抛出异常. ii. 创建Callable实现类 ...
- Java高并发与多线程(二)-----线程的实现方式
今天,我们开始Java高并发与多线程的第二篇,线程的实现方式. 通常来讲,线程有三种基础实现方式,一种是继承Thread类,一种是实现Runnable接口,还有一种是实现Callable接口,当然,如 ...
- java高并发系列 - 第11天:线程中断的几种方式
java高并发系列第11篇文章. 本文主要探讨一下中断线程的几种方式. 通过一个变量控制线程中断 代码: package com.itsoku.chat05; import java.util.con ...
- Java多线程并发01——线程的创建与终止,你会几种方式
本文开始将开始介绍 Java 多线程与并发相关的知识,多谢各位一直以来的关注与支持.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程的创建方式 在 Java 中,用户常用的主动创建 ...
- java高并发系列 - 第6天:线程的基本操作
新建线程 新建线程很简单.只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可. Thread thread1 = new Thread1(); t1.start(); 那么 ...
- 跟着阿里p7一起学java高并发 - 第18天:玩转java线程池,这一篇就够了
java中的线程池,这一篇就够了 java高并发系列第18篇文章. 本文主要内容 什么是线程池 线程池实现原理 线程池中常见的各种队列 自定义线程创建的工厂 常见的饱和策略 自定义饱和策略 线程池中两 ...
- java高并发系列 - 第10天:线程安全和synchronized关键字
这是并发系列第10篇文章. 什么是线程安全? 当多个线程去访问同一个类(对象或方法)的时候,该类都能表现出正常的行为(与自己预想的结果一致),那我们就可以所这个类是线程安全的. 看一段代码: pack ...
- Java高并发 -- 线程池
Java高并发 -- 线程池 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在使用线程池后,创建线程变成了从线程池里获得空闲线程,关闭线程变成了将线程归坏给线程池. ...
- Java高并发--线程安全策略
Java高并发--线程安全策略 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 不可变对象 发布不可变对象可保证线程安全. 实现不可变对象有哪些要注意的地方?比如JDK ...
- 转载:Java高并发,如何解决,什么方式解决
原文:https://www.cnblogs.com/lr393993507/p/5909804.html 对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并 ...
随机推荐
- 使用Redis时的vm.overcommit_memory内存分配控制
最近在使用Redis的时候遇到了linux系统中的vm.overcommit_memory参数设置,对此不是很了解,于是研究了一下,有了本文. ============================ ...
- 【转载】 t-SNE是什么? —— 使用指南
原文地址: https://www.cnblogs.com/LuckBelongsToStrugglingMan/p/14161405.html 转者前言: 该文相当于一个 t-SNE 使用指南, ...
- Python语言中当前工作目录(Current Working Directory, cwd)与模块搜索第一路径都是指什么???
相关: 查看并添加python中库的搜索路径 [python]自问自答:python -m参数? ( python3.7 版本 ) 本文主要解释Python语言中的两个基本概念: 当前工作目录(Cur ...
- 一些八股:1.fetch 的理解。2.let、const、var
一. 说说你对 Fetch 的理解,它有哪些优点和不足? Fetch API 是现代 JavaScript 中用于进行网络请求的接口,旨在替代传统的 XMLHttpRequest.它提供了一种更简单. ...
- 嵌入式数据库sqlite3【进阶篇】-子句和函数的使用,小白一文入门
在<嵌入式数据库sqlite3命令操作基础篇-增删改查,小白一文入门>一文中讲解了如何实现sqlite3的基本操作增删改查,本文介绍一些其他复杂一点的操作.比如where.order by ...
- 用whl文件安装Anaconda中的GDAL
本文介绍在Anaconda环境下,基于.whl文件安装Python中高级地理数据处理库GDAL的方法. 在之前的文章中,我们介绍了基于conda install命令直接联网安装GDAL库的方法 ...
- PCIe简介
PCIe简介 Peripheral Component Interconnect Express (PCI),高速串行计算机扩展总线标准,PCIe对外围设备的组织方式是树形结构. 拓扑结构 根: 树的 ...
- C++ was not declared in this scope
大概一搜百度,没搜到想要的结果,后面自己发现问题,由于是第二次犯这个错误(第一次很快发现,这一次找了比较久),所以记录一下 当调用一个数据结构或者一个函数的时候,出现这个语句,首先看相关的头文件有没有 ...
- chezmoi 使用
chezmoi(发音 /ʃeɪ mwa/ (shay-moi)):在多台不同的机器上安全地管理你的 dotfiles. 安装 macOS: brew install chezmoi Ubuntu: s ...
- 【Python】Selenium自动化测试之滑块拼图验证码图片方法
在项目中有时验证码是滑块拼图形式的,这种验证码该如何完成验证呢? 有以下几个步骤: 目录 第一步:得到验证码图片 第二步:匹配缺口照片在完整照片的位置 第三步:机器模拟人工滑动轨迹 第四步:判断拼图是 ...