JAVA中创建线程的三种方法及比较
JAVA中创建线程的方式有三种,各有优缺点,具体如下:
一、继承Thread类来创建线程
1、创建一个任务类,继承Thread线程类,因为Thread类已经实现了Runnable接口,然后重写run()方法,run()方法中的内容就是需要线程完成的任务。
2、创建一个任务类的对象,即创建了线程对象。
3、调用任务类对象的start()方法,来启动一个线程。
代码实例:
public class TestThread extends Thread {
public void run() {
for (int i = 0; i < 20; i++) {
// 与Thread.currentThread().getName()相同
System.out.println(this.getName() + " " + i);
}
}
public static void main(String[] args) {
TestThread t1 = new TestThread();
TestThread t2 = new TestThread();
t1.start();
t2.start();
}
}
二、实现Runnable接口来创建线程
1、创建一个任务类,实现Runnable接口,并实现run()方法,run()方法中的内容就是需要线程完成的任务。
2、创建一个任务类的对象。
3、任务类必须在线程中执行,因此将任务类的对象作为参数,创建一个Thread类对象,该Thread类对象才是真正的线程对象。
4、调用Thread线程类对象的start()方法,来启动一个线程。
代码实例:
public class TestThread implements Runnable {
public void run() {
for (int i = 0; i < 20; i++) {
// 获取线程名称,默认格式:Thread-0
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public static void main(String[] args) {
TestThread tt1 = new TestThread();
TestThread tt2 = new TestThread();
// 可为线程添加名称:Thread t1 = new Thread(tt1, "线程1");
Thread t1 = new Thread(tt1);
Thread t2 = new Thread(tt2);
t1.start();
t2.start();
}
}
三、通过Callable和Future来创建线程
1、创建一个任务类,实现Callable接口,并实现call()方法,call()方法中的内容就是需要线程完成的任务,且有返回值。
2、创建一个任务类的对象,并使用FutureTask类来包装任务类的对象,该FutureTask对象封装了任务类对象中call()方法的返回值。
3、任务类必须在线程中执行,因此将FutureTask类的对象作为参数,创建一个Thread类对象,该Thread类对象才是真正的线程对象。
4、调用Thread线程类对象的start()方法,来启动一个线程。
5、调用FutureTask类对象的get()方法来获取线程执行的返回值,即任务类对象中call()方法的返回值。
代码实例:
public class TestThread implements Callable<Integer> {
public Integer call() {
int i = 0;
for (i = 0; i < 20; i++) {
if (i == 5)
break;
System.out.println(Thread.currentThread().getName() + " " + i);
}
return i;
}
public static void main(String[] args) {
TestThread tt = new TestThread();
FutureTask<Integer> ft = new FutureTask<Integer>(tt);
Thread t = new Thread(ft);
t.start();
try {
System.out.println(Thread.currentThread().getName() + " " + ft.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、三种方式创建线程的比较
1、继承Thread类方式:
(1)优点:编写简单,任务类中访问当前线程时,可以直接使用this关键字。
(2)缺点:任务类即线程类已经继承了Thread类,所以不能再继承其他父类。
2、实现Runnable接口的方式:
(1)优点:任务类只实现了Runnable接口,还可以继承其他类。这种方式,可以多个线程对象共享一个任务类对象,即多线程共享一份资源的情况,如下:
TestThread tt1 = new TestThread();
Thread t1 = new Thread(tt1);
Thread t2 = new Thread(tt1);
t1.start();
t2.start();
(2)缺点:编写稍微复杂,任务类中访问当前线程时,必须使用Thread.currentThread()方法。
3、通过Callable和Future的方式:
(1)优点:任务类只实现了Callable接口,还可以继承其他类,同样多线程下可共享同一份资源,这种方式还有返回值,并且可以抛出返回值的异常。
(2)缺点:编写稍微复杂,任务类中访问当前线程时,必须使用Thread.currentThread()方法。
总结:在仅仅只重写run()方法,而不重写Thread类其他方法的前提下,比较推荐实现Runnable接口的方式创建线程。因为不打算修改或增强类的基本能力,不应该为其创建子类。而且实现Runnable接口的方式,线程和资源相对分离,程序更加健壮,更符合面向对象的编程思想。当然,需要线程有返回值时可以使用Callable的方式,但Callable的方式有一个问题,当调用get()方法时,如果线程还未执行完毕,则会阻塞到线程执行完毕拿到返回值。
JAVA中创建线程的三种方法及比较的更多相关文章
- Java中创建线程的三种方法以及区别
Java使用Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例.Java可以用三种方式来创建线程,如下所示: 1)继承Thread类创建线程 2)实现Runnable接口创建线 ...
- Java中创建线程的三种方式以及区别
在java中如果要创建线程的话,一般有3种方法: 继承Thread类: 实现Runnable接口: 使用Callable和Future创建线程. 1. 继承Thread类 继承Thread类的话,必须 ...
- Java中终止线程的三种方法
终止线程一般建议采用的方法是让线程自行结束,进入Dead(死亡)状态,就是执行完run()方法.即如果想要停止一个线程的执行,就要提供某种方式让线程能够自动结束run()方法的执行.比如设置一个标志来 ...
- java中创建线程的几种方法及区别
1,实现Runnable接口创建线程 特点: A:将代码和数据分开,形成清晰的模型 B:线程体run()方法所在的类可以从其它类中继承一些有用的属性和方法 C:有利于保持程序风格的一致性 2,继承Th ...
- java中创建线程的3种方法
1.继承Thread类优点:可以直接使用Thread类中的方法,代码比较简单.缺点:继承Thread类之后不能继承其他类. 2.实现Runable接口优点:实现接口,比影响继承其他类或实现接口.缺点: ...
- Java中创建线程的三种方式及其优缺点
1.自定义一个继承Thread的类,由于Java的单继承特性,限制了该类的扩展性. 2.实现Runnable接口,重写run()方法. 3.实现Callable接口,重写call方法.线程执行体可以有 ...
- java创建线程的三种方法
这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...
- 《Java多线程面试题》系列-创建线程的三种方法及其区别
1. 创建线程的三种方法及其区别 1.1 继承Thread类 首先,定义Thread类的子类并重写run()方法: package com.zwwhnly.springbootaction.javab ...
- Java中创建数组的几种方法
Java中创建数组的几种方法 public static void main(String[] args) { //创建数组的第一种方法 int[] arr=new int[6]; int intVa ...
随机推荐
- 三十分钟学会AWK
摘要: 本文大部分内容翻译自我开始学习AWK时看到的一篇英文文章 AWK Tutorial ,觉得对AWK入门非常有帮助,所以对其进行了粗略的翻译,并对其中部分内容进行了删减或者补充,希望能为对AWK ...
- 做了一个web版的 MyBatis Generator
mybatis 官方提供了 MyBatis Generator ,可以通过 xml 配置文件的方式使用,例如自己写调用脚本,或者使用 mvn 插件的方式,其实实现起来还是很简单的.虽然简单,但还是不够 ...
- input表单的type属性详解,不同type不同属性之间区别
目标:详解表单input标签type属性常用的属性值 一.input标签和它的type属性 PS:input 元素可以用来生成一个供用户输入数据的简单文本框. 在默认的情况下, 什么样的数据均可以输入 ...
- Ajax提交Form表单的一种方法
待提交的表单 <form id="updatePublicKey" enctype="multipart/form-data"> <div c ...
- Spring读取外部属性-properties
概述 在Spring中处理外部值最简常用的方法就是外部创建name.properties文件,并在其中声明变量值,供Java进行读取.比如数据源信息配置,Java固定属性位置等.读取的方式一般由三种: ...
- Java与算法之(10) - 希尔排序
希尔排序是插入排序的一种,是直接插入排序的改进版本. 对于上节介绍的直接插入排序法,如果数据原来就已经按要求的顺序排列,则在排序过程中不需要进行数据移动操作,即可得到有序数列.但是,如果最初的数据是按 ...
- Messagepack原理
什么是Messagepack? 用官方的话说:MessagePack是一种高效的二进制序列化格式.它允许您像JSON一样在多个语言之间交换数据.但是,它更快并且更小.小整数被编码为一个字节,和典型的短 ...
- OOAD-设计模式(一)概述
前言 在我们很多时候设计代码都是需要用到各种不一样的设计模式的,接下来着几篇给大家领略一下设计模式.知道设计模式的作用,以及在代码的具体体现.很多时候我们看不懂代码就是因为我们不知道它使用的设计模式. ...
- 【Java学习笔记之二十三】instanceof运算符的用法小结
instanceof运算符用法 运算符是双目运算符,左面的操作元是一个对象,右面是一个类.当左面的对象是右面的类创建的对象时,该运算符运算的结果是true,否则是false 说明: (1)一个类的实例 ...
- [51nod Round15 E ]Danganronpa
AC自动机,树上莫队,树状数组.. 比赛的时候完全看不出来...赛后去膜了一波网上题解才明白= = 离线,先把AC自动机建出来,把fail边反向建出fail树. 发射言弹,就是将言弹结束节点的fail ...