Java创建并执行线程的四种方法

Java创建并执行线程的四种方法

java里面创建线程有四种方式:
无返回:

  1. 实现Runnable接口,重写run();
  2. 继承Thread类,重写run();
    有返回:
  3. 实现Callable接口,重写call(),利用FutureTask包装Callable,并作为task传入Thread构造函数;
  4. 利用线程池;

下面来看看具体的创建方式:
5. 继承Thread类,重写run();
创建:创建线程只需要继承Thread类,然后在run方法里写下线程要实现的任务即可;
在这里插入图片描述
调用:通过调用start方法来启动线程而不能直接调用run方法。
在这里插入图片描述

① Thread类本质上是实现了Runnable接口,Thread对象代表一个线程的实例。
② Runnable接口只有一个抽象的run()方法。
③ 启动线程的唯一方法就是通过Thread类的start()实例方法。
④ start()方法是一个native方法,它将启动一个新线程,并执行run()方法。
⑤ 自定义类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
6. 创建任务,实现Runnable接口,重写run()。(受欢迎)
因为Java只能单继承,继承了Thread类就不能再继承别的类了所以实现继承更推崇的是让线程类实现Runnable接口。
在这里插入图片描述
将Runnbale作为参数传入Thread的构造函数,创建Thread.
在这里插入图片描述
3. Callable接口只包含抽象方法V call()。
在这里插入图片描述
利用Callable接口创建并启动新线程的步骤:
① 定义MyClass实现Callable接口;Class MyClass implements Callable
② 重写call(),将执行的代码写入;
③ 创建FutureTask的对象;FutureTask中定义了run(),run()内部调用了call(),并保存了call()的返回值;FutureTask futuretask = new FutureTask(newMyClass());
④ 创建Thread的对象;Thread thread = new Thread(futuretask);//传入参数Runnable接口
⑤ 启动线程;thread.start();[图片]
⑥ 可通过FutureTask类的get()方法获得线程执行结束后的返回值,即call的返回值。futuretask.get();

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;public class MyThread {public static void main(String[] args) throws InterruptedException {FutureTask<Integer> task = new FutureTask<Integer>(new CallableImpl());Thread thread = new Thread(task);thread.start();try {System.out.println("task.get() returns " + task.get());} catch (ExecutionException e) {e.printStackTrace();}}
}class CallableImpl implements Callable<Integer> {private static Integer value = 0;@Overridepublic Integer call() throws Exception {System.out.println("执行call方法之前 value = " + value);value = value.intValue() + 1;System.out.println("执行call方法之后 value = " + value);return value;}
}

运行结果:
执行call方法之前 value = 0
执行call方法之后 value = 1
task.get() returns 1
4. 通过线程池来创建线程
① new ThreadPoolExecutor(…);
② 创建任务Task implements Callable,重写run()方法;
③ 通过线程池的execute()或submit()将任务command传入线程池;
④ 获取返回值:

  1. 实现Callable接口,重写call()方法
    class CallableImpl implements Callable
  2. 定义线程池
    ThreadPoolExecutor executor
  3. 利用submit()方法提交任务
    Future<?> future = executor.submit(new CallableImpl());
  4. 利用FutureTask类get()方法获取返回值
    res = task.get();
    这里future申明为Future对象,但是它是由FutureTask实现的,也可以直接申明为FutureTask future:
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;public class MyThreadPool {public static void main(String[] args) throws InterruptedException, ExecutionException {ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 10, 200, TimeUnit.MILLISECONDS,new ArrayBlockingQueue<Runnable>(20));Future task;for (int i = 0; i < 5; i++) {task = executor.submit(new CallableImpl());System.out.println("线程返回结果:" + task.get());}executor.shutdown();}
}class RunnableImpl implements Runnable {@Overridepublic void run() {// TODO Auto-generated method stubSystem.out.println("hhh");System.out.println(Thread.currentThread().getName());}
}

运行结果:
执行call方法之前 value = 0
执行call方法之后 value = 1
线程返回结果:1
执行call方法之前 value = 1
执行call方法之后 value = 2
线程返回结果:2
执行call方法之前 value = 2
执行call方法之后 value = 3
线程返回结果:3
执行call方法之前 value = 3
执行call方法之后 value = 4
线程返回结果:4
执行call方法之前 value = 4
执行call方法之后 value = 5
线程返回结果:5

总结:
线程的创建有四种方式:主要分为有返回和无返回,具体根据使用场景来选择。

  1. 如果不需要返回且线程数量小,则建议采用实现Runnable接口,重写run()的方式;
  2. 如果需要返回且线程数量小,则建议采用实现Callable接口,重写call(),利用FutureTask包装成一个Runnable,再作为参数传入Thread的构造方法的方式创建线程;
  3. 如果线程数量较多,则建议采用线程池方式创建:execute提交任务实现无返回操作,submit提交任务实现有返回操作。

补充:FutureTask
JDK1.8中FutureTask实现了RunnableFuture,而RunnableFuture顾名思义就是Runnable接口和Future接口的结合体。因此,FutureTask对象可以作为Runnable对象来用,比如

    Thread thread = new Thread(new FutureTask<V>());

也可以作为Future来用。这就是Java的有魅力的地方。。。

    public class FutureTask<V> implements RunnableFuture<V>public interface RunnableFuture<V> extends Runnable, Future<V> {void run();}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/557330.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea中svn的更新、检出、提交操作

一、首先集成svn到idea 点击号连接svn仓库地址 等待代码下载完毕后就可以对代码进行update,commit操作了 更新操作方法一:项目上右键 方法二:点击快捷图标 方法三: 代码提交 方法一 方法二: 方法三: 会跳出窗口: 然后点击Commit 如果检测代码有错误会询问你是否要处理,一般确定…

判断链表是否相交并找出交点

问题概述 单链表定义如下&#xff1a; public class ListNode {int val;ListNode next;ListNode(int x) {val x;next null;}}编写程序&#xff0c; 找出两个链表的交点。 如图所示&#xff0c;链表 A 和链表 B 在节点 8 处相交。 算法思路 首先确定一个事情&#xff1a; …

兄弟3150cdn更换硒鼓_耗材知多点:一体式硒鼓及分离式硒鼓

相信第一次接触硒鼓的小伙伴们&#xff0c;会比较诧异为什么有些硒鼓可以直接装机使用&#xff0c;而有些硒鼓&#xff0c;却需要两个部件组合起来或分别装机才能正常使用。今天就带大家来了解一下什么是一体式硒鼓&#xff0c;什么又是分离式硒鼓。①一体式硒鼓&#xff1a;以…

Java IO流之PrintStream分析

简介 PrintStream继承了FilterOutputStream.是"装饰类"的一种,所以属于字节流体系中(与PrintStream相似的流PrintWriter继承于Writer,属于字符流体系中),为其他的输出流添加功能.使它们能够方便打印各种数据值的表示形式.此外,值得注意的是: 与其他流不同的是,Prin…

bs4爬取的时候有两个标签相同_10分钟用Python爬取最近很火的复联4影评

《复仇者联盟4&#xff1a;终局之战》已经上映快三个星期了&#xff0c;全球票房破24亿美元&#xff0c;国内票房破40亿人民币。虽然现在热度逐渐下降&#xff0c;但是我们还是恬不知耻地来蹭一蹭热度。上映伊始《复联4》的豆瓣评分曾破了9分。后来持续走低&#xff0c;现在《复…

RabbitMQ 基本概念与高级特性

文章目录1. 什么是消息队列1.1 消息队列概述1.2 使用消息队列的优势1.3 使用消息队列的劣势1.4 常见的消息队列产品对比2. RabbitMQ 基本概念2.1 RabbitMQ 概述2.2 RabbitMQ 的概念模型2.2.1 Message2.2.2 Publisher2.2.3 Exchange2.2.4 Binding2.2.5 Queue2.2.6 Connection2.2…

HTTP 和 SOCKET 的区别

HTTP 和 SOCKET 的区别 要弄明白 http 和 socket 首先要熟悉网络七层&#xff1a;物 数 网 传 会 表 应&#xff0c;如图1 如图1 HTTP 协议:超文本传输协议&#xff0c;对应于应用层&#xff0c;用于如何封装数据. TCP/UDP 协议:传输控制协议&#xff0c;对应于传输层&…

java 8进制串转中文_为什么不能用中文进行编程?而英文就可以

前些天大雄无意间听见几个线下班小伙伴说真的是无(te)意(di)的“我要补英文”“对&#xff0c;英文真的很重要”“如果编码用中文就好了”...听见这大雄就不淡定了中文代码小伙伴确定能够搞懂&#xff1f;&#xff1f;首先我们大概的看一下中文编码&#xff1a;你以为会写中文写…

MATLAB学习笔记(一)求解三阶微分方程

一、求解三阶微分方程 对于多变量三阶微分方程求解问题&#xff0c;这里介绍一种求解方法。 例题如下&#xff1a; 对于以上方程&#xff0c;给定边界条件&#xff0c;&#xff0c;&#xff0c;&#xff0c;&#xff0c;。求解和的表达式。 二、解题步骤 &#xff08;1&…

axure 内部框架内容下滑_Axure教程:转盘抽奖交互原型

本文跟大家分享&#xff0c;如何使用axure制作转盘抽奖交互原型&#xff0c;不带登录流程。效果如下&#xff1a;抽奖流程一、主要内容(1)主要元件&#xff1a;动态面板(2)重点&#xff1a;旋转交互、随机函数、触发动作。(3)难点&#xff1a;通过停止位置判断抽奖结果(4)涉及函…

日志打印的8种级别(很详细)

日志打印的8种级别&#xff08;很详细&#xff09; 日志的输出都是分级别的&#xff0c;不同的设置不同的场合打印不同的日志。下面拿最普遍用的Log4j日志框架来做个日志级别的说明&#xff0c;其他大同小异。 Log4j的级别类org.apache.log4j.Level里面定义了日志级别&#x…

identity_insert 如何改为on_十分钟教你如何快速提高Laya构建速度,还不快来康康?...

前言如何快速提高Laya构建速度 微信小游戏推出之后&#xff0c;很多公司也相应的进入到微信小游戏这个领域&#xff0c;现在市场上的游戏开发引擎&#xff0c;如Cocos、Egret、Laya都对小游戏有了很好的兼容性。而在实际开发中&#xff0c;如何提高Laya的构建速度&#xff0c;是…

二下语文书电子课本_小学生语文成绩好,不是靠补课,把课本吃透,才是高效学习方法...

关注语文教学发展&#xff0c;解决语文学习困惑。对于基础差、语文学习能力差的同学&#xff0c;我不建议去补课。但是家长说&#xff0c;不补课怎么办呢&#xff1f;我们也没有时间和耐心去给孩子辅导&#xff0c;又怕讲错了&#xff0c;还是让老师讲好。尽管家长们有这个意识…

Java面试——MyBatis系列总结

文章目录&#xff1a; 1.MyBatis是什么&#xff1f; 2.JDBC编程有哪些缺陷&#xff1f;MyBatis又是如何改进的&#xff1f; 3.MyBatis与Hibernate的区别在哪&#xff1f; 4.MyBatis的优缺点 5.请说说MyBatis的工作原理 6.MyBatis的架构设计是怎样的&#xff1f; 7.#{}和…

Java面试——Spring系列总结

文章目录&#xff1a; 1.什么是Spring&#xff1f; 2.Spring由哪些模块组成&#xff1f; 3.Spring中都用到了哪些设计模式&#xff1f; 4.什么是Spring IOC容器&#xff1f;有什么作用&#xff1f; 5.Spring IoC的实现机制 6.BeanFactory 和 ApplicationContext有什么区别…

Spring bean 不被 GC 的真正原因

概述 自从开始接触 Spring 之后&#xff0c;一直以来都在思考一个问题&#xff0c;在 Spring 应用的运行过程中&#xff0c;为什么这些 bean 不会被回收&#xff1f; 今天深入探究了这个问题之后&#xff0c;才有了答案。 思考点 大家都知道&#xff0c;一个 bean 会不会被回…

vts传感器采取船舶的_详解虎门大桥监测系统:传感器与物联网功不可没

来源&#xff1a;传感器专家网近日&#xff0c;虎门大桥“虎躯一震”给全国人民来了个“深呼吸”。虎门大桥是广东沿海地区重要的交通枢纽&#xff0c;始建于1992年&#xff0c;1997年通车至今&#xff0c;大桥一直都十分平稳。但在5月5日下午&#xff0c;虎门大桥发生异常抖动…

MySQL 排名函数.md

概述 MySQL 自带的排名的函数&#xff0c;主要有&#xff1a; row_number()rank()dense_rank()ntile() 测试数据 测试数据如下所示&#xff1a; row_number() 函数 用法如下&#xff1a; SELECT row_number() OVER (ORDER BY Salary DESC) row_num,Salary FROMEmployee查…

深度学习auc_机器学习集成学习与模型融合!

↑↑↑关注后"星标"Datawhale每日干货 & 每月组队学习&#xff0c;不错过Datawhale干货 作者&#xff1a;李祖贤&#xff0c;深圳大学&#xff0c;Datawhale高校群成员对比过kaggle比赛上面的top10的模型&#xff0c;除了深度学习以外的模型基本上都是集成学习的…

数控车椭圆编程实例带图_数控车床编程教程,图文实例详解

一、数控车编程特点(1) 可以采用绝对值编程(用X、Z表示)、增量值编程(用U、W表示)或者二者混合编程。(2) 直径方向(X方向) 系统默认为直径编程&#xff0c;也可以采用半径编程&#xff0c;但必须更改系统设定。(3) X向的脉冲当量应取Z向的一半。(4)采用固定循环&#xff0c;简化…