首页 > 其他分享 >线程创建方式

线程创建方式

时间:2023-10-31 13:24:58浏览次数:28  
标签:Runnable 方式 Thread 创建 实例 线程 方法

1.Thread 通过继承Thread的方式,可以创建一个线程,需要重写其中的run方法,启动线程时,通过调用start方法启动。形如:

2.Runnable 通过实现Runnable接口的方式,可以创建一个线程,需要重写其中的run方法,启动线程时,将自定义类的实例作为一个参数,调用Thread的构造方法,得到一个线程实例,再调用start方法启动。形如:

3.Callable 通过实现callable接口的方式,可以创建一个线程,需要重写其中的call方法。启动线程时,需要新建一个Callable的实例,再用FutureTask实例包装它,最终,再包装成Thread实例,调用start方法启动,并且,可以通过FutureTask的get方法来获取返回值。形如:

4.线程池 了解了以上三种线程的创建方式,线程池就好理解了。它相当于事先为我们准备好了一些线程,放到池子里。我们需要的时候,取用就可以了,而不需要自己创建。 线程池的线程,一定是通过实现Runnable或Callable接口的方法创建的,通过继承Thread类创建的线程实例,无法放到线程池中。 线程创建(两种方式): 1.ThreadPoolExecutor构造函数(推荐):

 2.通过Executer框架的工具类Executors创建 

newCachedThreadPool-----》创建一个可缓存线程池,如果线程池长度超过需要处理需要,克灵活回收空线程,若无可回收,则新建线程。
newFixedThreadPool------>创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newSchedulThreadPool----》创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor----->创建一个单线程化的线程池,它会只用唯一的工作线程来执行任务,保证所有任务按照指定顺序FIFO、LIFO,优先级执执

Thread和Runnable 我们先来看Thread和Runnable,最直接的区别是,Thread是一个类,需要继承,而Runnable是一个接口,需要实现。我们知道,Java中,是单继承多实现的,即一个类,通过extends只能继承一个类,而通过implements关键字,可以实现多个接口。所以,就这两种方法而言,更推荐使用实现Runnable接口的方式。这样,extends可以留给更需要的人。 Runnable还有一个优势,我们可以通过分析Thread的源码发现。Thead类中,有一个属性,类型是Runnable,名称是target。也就是说,当我们调用start方法启动线程后,事实上在运行时,执行的是target的run方法。注意我们在使用Runnable时做的事情,是先new了一个Runnable类的实例,再将其包装成一个Thread的实例,再执行start方法,就好像是我们把Runnable和Thread作了一定程度的解耦,换句话说,我们把线程的创建和具体的业务做了解耦。这样的好处是什么?一是代码和数据独立,二是多线程可以共享同一个资源。 代码和数据独立很好理解,那么,多线程共享资源是什么意思?看如下:

我们看到,创建了两个线程,但是它们使用了同一个Runnable实例。也就意味着,如果Runnable实例中包含一个类变量,比如count,那么,两个线程对count的操作是相互影响的,也就是说,count这个变量是两个线程共享的,Runnable实例是两个线程共享的。   Callable的特殊之处 Callable的特殊之处,从它的用法就可以看得出来。首先,它的执行方法call有返回值。查看Callable接口的源码,发现它还支持通过泛型的方式,来规定call方法的返回值,这使我们的使用更加灵活。 call方法和Runnable的run方法还有一个不同点是可以抛出异常。看源码得知,它会抛出Exception异常。 也就是说,Callable接口给我们带来了更加灵活的线程使用体验,不仅可以去获取一个线程的返回值,还可以对线程中出现的异常进行处理。例如,我们在示例代码中,调用了FutureTask的get方法。这个方法就能够得到Callable中call方法的返回值。 事实上,我们看下FutureTask的源码就会发现,它实现了RunnableFuture接口,而RunnableFuture又继承了Runnable和Future接口(Java的接口可以多继承)。这也就使得FutureTask能够作为Thread构造方法的一个参数,又能通过get方法来获取到返回值。 这里还有一个点是,get方法会使当前线程等待得到返回值。换句话说,如果A线程中通过调用了get方法,要取得B线程的返回值。那么,A线程在执行到get方法时,如果B线程还没有执行完毕,A线程就会等待,一直等到B线程执行完成,A线程才会继续运行。为什么这里用了“等待”这个词来描述,而没有使用阻塞呢?这点,我们通过get方法的源码可以看出来。 我们发现,get方法调用了一个awaitDone的方法,该方法有如下关键代码:

省略了与本文无关的代码。我们发现,这里有个关键点是,当判断s == COMPLETING时,就会执行Thread的yield方法。这个方法的作用就是使当前线程进入就绪状态,而不是阻塞状态。  

标签:Runnable,方式,Thread,创建,实例,线程,方法
From: https://www.cnblogs.com/cjhtxdy/p/17800018.html

相关文章

  • java mysql druid mybatis-plus里使用多表删除出错的一种处理方式
    今天在出来多表删除的时候在mapper.xml用了下面的多个delete语句<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespa......
  • 10月31日线程基础
    目录线程基础线程的概念如果把操作系统当成一个工厂进程之间是竞争关系,线程之间是什么关系纠正概念进程与线程的区别是什么?线程基础线程的概念在操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程线程顾名思义,就是一条流水线工作的过程,可以这么想一条流水线必须属于......
  • Opencascad(C++)-建模-创建有界直线段
    文章目录1、前言2、用gp_Lin创建一条直线2.1gp_Lin类成员函数2.2创建一条直线2.3运行结果3、创建一条有界的直线段3.1功能说明3.2函数说明3.2创建直线段的代码3.3测试效果1、前言在Opencascad开发时,经常会遇到创建直线的情况,采用gp_Line创建的直线段是无界的,如果想创建......
  • 【ROS2机器人入门到实战】动手创建一个移动机器人
    8.3动手创建一个移动机器人写在前面当前平台文章汇总地址:ROS2机器人从入门到实战获取完整教程及配套资料代码,请关注公众号<鱼香ROS>获取教程配套机器人开发平台:两驱版|四驱版为方便交流,搭建了机器人技术问答社区:地址fishros.org.cn大家好,我是小鱼,本节课我们来一起动手创建一个两......
  • LINUX下ORACLE表空间及用户创建
    LINUX下ORACLE表空间及用户创建 记录详细过程以备使用 ConnectedtoOracleDatabase11gEnterpriseEditionRelease11.2.0.1.0Connectedassys@ip:port/sid ASSYSDBA 管理员用户登录oracle数据库 1、创建临时表空间selectnamefromv$tempfile;查出当前数......
  • 多线程,多进程,协程,IO多路复用
    关于PythonPython有多进程,且原生支持协程,但是由于GIL全局锁的存在,Python只有假多线程,即单线程轮流执行多个任务,常用于IO任务的阻塞等待当中。多线程即一种基于内核态工作的异步运行方式。对于多核CPU而言,只有多线程和多进程才能真正的充分调用CPU的多核工作。但是由于用户态向......
  • 两种方式讲链表节点删除
    第一种讲法就是循环的方式,因为要循环遍历这个链表,所以我们会运用到一个很重要的哨兵思想,就是定一个没啥意义的哨兵,让head“makesense”,接着,我们的任务是对链表进行删除,那就涉及到一个前端链表的指向问题,但是现在这个是单向链表,我们无法知道你前面那个是谁,所以我们也可以想办法......
  • Lock实现线程间定制化通信
    Lock实现线程间定制化通信案例要求三个线程,AABBCCAA线程打印5次,BB线程打印10次,CC线程打印15次代码实现importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;/***@author长名06......
  • JAVA-EE手写ThreadLocal源码实现一个线程一个连接对象------Java-Web项目
    手写ThreadLocalpackagecom.bjpowernode.ThreadLocal;importjava.util.HashMap;importjava.util.Map;publicclassMyThreadLocal<T>{privateMap<Thread,T>map=newHashMap<>();publicvoidset(To){//向threadLocal中绑定......
  • Unity 创建自定义渲染管线
    可以看官方的https://docs.unity3d.com/Manual/srp-custom-getting-started.html或者这位大佬的https://zhuanlan.zhihu.com/p/378828898......