首页 > 编程语言 >java中创建线程的三种方法以及区别

java中创建线程的三种方法以及区别

时间:2023-08-23 17:25:13浏览次数:60  
标签:java Thread 创建 接口 Callable 线程 三种 方法

java中创建线程的三种方法以及区别

 

Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。Java可以用三种方式来创建线程,如下所示:

1)继承Thread类创建线程

2)实现Runnable接口创建线程

3)使用Callable和Future创建线程

下面让我们分别来看看这三种创建线程的方法。

 

------------------------继承Thread类创建线程---------------------

 

通过继承Thread类来创建并启动多线程的一般步骤如下

1】d定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。

2】创建Thread子类的实例,也就是创建了线程对象

3】启动线程,即调用线程的start()方法

代码实例

public class MyThread extends Thread{//继承Thread类

  public void run(){

  //重写run方法

  }

}

public class Main {

  public static void main(String[] args){

    new MyThread().start();//创建并启动线程

  }

}

------------------------实现Runnable接口创建线程---------------------

通过实现Runnable接口创建并启动线程一般步骤如下:

1】定义Runnable接口的实现类,一样要重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体

2】创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象

3】第三部依然是通过调用线程对象的start()方法来启动线程

代码实例:

public class MyThread2 implements Runnable {//实现Runnable接口

  public void run(){

  //重写run方法

  }

}

public class Main {

  public static void main(String[] args){

    //创建并启动线程

    MyThread2 myThread=new MyThread2();

    Thread thread=new Thread(myThread);

    thread().start();

    //或者    new Thread(new MyThread2()).start();

  }

}

------------------------使用Callable和Future创建线程---------------------

和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。

》call()方法可以有返回值

》call()方法可以声明抛出异常

Java5提供了Future接口来代表Callable接口里call()方法的返回值,并且为Future接口提供了一个实现类FutureTask,这个实现类既实现了Future接口,还实现了Runnable接口,因此可以作为Thread类的target。在Future接口里定义了几个公共方法来控制它关联的Callable任务。

>boolean cancel(boolean mayInterruptIfRunning):视图取消该Future里面关联的Callable任务

>V get():返回Callable里call()方法的返回值,调用这个方法会导致程序阻塞,必须等到子线程结束后才会得到返回值

>V get(long timeout,TimeUnit unit):返回Callable里call()方法的返回值,最多阻塞timeout时间,经过指定时间没有返回抛出TimeoutException

>boolean isDone():若Callable任务完成,返回True

>boolean isCancelled():如果在Callable任务正常完成前被取消,返回True

介绍了相关的概念之后,创建并启动有返回值的线程的步骤如下:

1】创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。

2】使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值

3】使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)

4】调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

代码实例:

public class Main {

  public static void main(String[] args){

   MyThread3 th=new MyThread3();

   //使用Lambda表达式创建Callable对象

     //使用FutureTask类来包装Callable对象

   FutureTask<Integer> future=new FutureTask<Integer>(

    (Callable<Integer>)()->{

      return 5;

    }

    );

   new Thread(task,"有返回值的线程").start();//实质上还是以Callable对象来创建并启动线程

    try{

    System.out.println("子线程的返回值:"+future.get());//get()方法会阻塞,直到子线程执行结束才返回

    }catch(Exception e){

    ex.printStackTrace();

   }

  }

}

--------------------------------------三种创建线程方法对比--------------------------------------

实现Runnable和实现Callable接口的方式基本相同,不过是后者执行call()方法有返回值,后者线程执行体run()方法无返回值,因此可以把这两种方式归为一种这种方式与继承Thread类的方法之间的差别如下:

1、线程只是实现Runnable或实现Callable接口,还可以继承其他类。

2、这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。

3、但是编程稍微复杂,如果需要访问当前线程,必须调用Thread.currentThread()方法。

4、继承Thread类的线程类不能再继承其他父类(Java单继承决定)。

标签:java,Thread,创建,接口,Callable,线程,三种,方法
From: https://www.cnblogs.com/jinfangwei/p/17652238.html

相关文章

  • Java基础
    一、注释单行注释//多行注释 /*我是多行注释*/文档注释Javadoc/***@Description:HelloWorld*@Author:SYL*/二、标识符和关键字    三、数据类型 浮点数是有限的离散的舍入误差大约接近但不等于的值      变量:可以变化的量每......
  • 软件测试 | Java中的关键字
    Java中也有许多关键字(也叫保留字),如public、static等,这些关键字不能当做标识符使用。表2-1列出了Java中的关键字,这些关键字并不需要去硬背,因为在程序开发中一旦使用了这些关键字做标识符时,编辑器会自动提示错误。对于以上的关键字,要特别注意的有如下3点:(1)虽然goto、const在Java中并没......
  • 软件测试 | Java程序的注释
    在任何编程语言之中,都存在注释,注释的主要功能是让其他用户可以方便地阅读每段程序,提高程序的可读性,还可以通过注释屏蔽掉一些暂时不用的语句,等需要时直接取消此语句的注释即可,在Java中根据功能的不同,注释主要分为单行注释、多行注释、文档注释3种,下面分别进行介绍。单行注释,就是在......
  • 软件测试 | 一个简单的Java范例
    下面给出一个简单的Java程序范例,观察Java成都基本结构及相同点。范例:定义一个简单类publicclassTestJava{publicstaticvoidmain(String[]args){//Java操作的一个简单范例,输出和乘方intnum=10;......
  • 软件测试 | 编写第一个Java程序
    Java程序分为两种类型,一种是Application程序,另外一种是Applet程序,其中有main方法的程序主要都是Application程序。还是以输出“HelloWorld!!”字符串为第一个程序,代码如下所示。范例:Hello.javapublicclassHello{publicstaticvoidmain(Stringargs[]){System.out......
  • Java 运算符 - 除法
    1.除法运算符Java中的除法运算符是“/”符号,表示将左侧操作数除以右侧操作数。2.整数除法在Java中,整数除法的结果是一个整数,即只保留除法的整数部分,舍去小数部分。例如,7/2的结果是3,而不是3.5。3.浮点数除法如果操作数中至少有一个是浮点数,则Java会执行浮点数除法,结果为一......
  • 动力节点Java开发小技能:两小时生成二维码教程
    随着互联网的快速发展,二维码逐渐成为了主流,日常生活已经离不开二维码了,它们变得越来越有用。从候车亭、产品包装、家装卖场、汽车到很多网站,都在自己的网页二维码,让人们快速找到它们。随着智能手机的用户量日益增长,二维码的使用正在呈指数上升。让我们来看看如何在Java中生成它们。......
  • Java代理模式初探
    代理模式是一种常见的软件设计模式。所谓的代理者是指一个类别可以作为其它对象的接口。代理者可以作任何东西的接口:网络连接、存储器中的大对象、文件或其它重要或无法复制的资源。有时候我们需要需要一个功能(通常是一个API)。该功能已经被某个类A实现了,代理类B实现相同的接口,并将......
  • Java简单实现大数相加
    Java简单实现大数相加publicclassBigNumberAdd{/***假设两个都是正数*@paramnum1*@paramnum2*@returnnum1+num2*/publicstaticStringadd(Stringnum1,Stringnum2){intm=num1.length();intn=......
  • java 读取各种类型的文件 (三)
    后端java,springboot、前端vue:对txt文件的读写,以及前端预览一、后端读publicvoidreadTxt(){InputStreamReaderinput=null;BufferedReaderbuffer_reader=null;ArrayBlockingQueue<String[]>fileData=new......