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 ...
随机推荐
- Django源码分析之程序执行入口分析
一般我们开启一个django项目,最简单的方法是进入project 目录,这时目录结构是这样的 然后我们执行python manage.py runserver,程序就开始执行了. 那django是如 ...
- IdentityServer Topics(6)- Windows身份验证
在支持的平台上,您可以让IdentityServer使用Windows身份验证(例如,对Active Directory)对用户进行身份验证. 当您使用以下身份托管IdentityServer时,当前 ...
- JavaScript基础知识(正则表达式、字符串)
23.正则表达式 作用:定义一个特定的验证字符串内容规则的表达式 注:正则表达式并不是JavaScript独有的:JavaScript支持正则表达式 var a = { }; // 定义一个空对象 ...
- TCP/IP和UDP之间的区别(转载)
在分析两者之间的区别之前,我们先搞清楚这两者的关系, TCP/IP协议簇 是一种网络控制协议,简单点说就是一种网络协议,我们网络中的计算机就是通过这套协议簇来进行数据通信的.这套协议簇里面包含了很多 ...
- Rosenblatt感知器
一.定义 Rosenblatt感知器建立在一个线性神经元之上,神经元模型的求和节点计算作用于突触输入的线性组合,同时结合外部作用的偏置,对若干个突触的输入项求和后进行调节. 二.基本计算过程 Rose ...
- windows sevser 2012搭建网站
1,首先去服务器配置,从哪里下载iis8.0和asp.net和net.xx和web服务,iis控制,ftp等等服务根据自己的需求安装 安装好后把默认的网站删除掉.或者新建一个网站,把服务端口改为其他端 ...
- CSS3让长单词与URL地址自动换行——word-wrap属性
div{ word-wrap:break-word; } word-wrap属性可以使用的属性值为normal与break-word两个.使用normal属性值时浏览器默认处理,只在半角空格或者连字符 ...
- bzoj 2946
Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单词 l 计算最长公共子串的长度 l 输 ...
- BZOJ3529: [Sdoi2014]数表
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3529 挺恶心的数论TAT... 设f[i]是i的约数和,这个可以nln(n)扫出来. ans= ...
- BZOJ 3106: [cqoi2013]棋盘游戏(对抗搜索)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3106 对抗搜索,f[x][y][a][b][c][d]表示当前谁走,走了几步,及位置. (因为 ...