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 ...
随机推荐
- Redis Sentinel配置小记
Sentinel是一个管理多个redis实例的工具,它可以实现对redis的监控.通知.自动故障转移.sentinel不断的检测redis实例是否可以正常工作,通过API向其他程序报告redis的状态 ...
- Talking appsettings.json in Asp.Net Core
在ASP.NET Core中,默认提供了三个运行时环境变量,通过查看Hosting源代码我们可以看到,分别是Development.Staging.Production public static c ...
- 【CentOS】阿里云CentOS安装php环境
本文在介绍安装php环境前,已安装了nginx.mysql. 一.安装 使用国内的搜狐镜像站下载php5.6安装包,执行: wget http://mirrors.sohu.com/php/php- ...
- java实现 比较两个文本相似度-- java 中文版 simHash 实现 ,
比较两个文本的相似度 这里采用 simHash 算法 ; 分词是 基于 http://hanlp.linrunsoft.com/ 的开源 中文分词包 来实现分词 ; 实现效果图: 直接上源码: htt ...
- iptables网络安全服务详细使用
iptables防火墙概念说明 开源的基于数据包过滤的网络安全策略控制工具. centos6.9 --- 默认防火墙工具软件iptables centos7 --- 默认防火墙工具软件fire ...
- html笔记3
继续记录 继续上次的img标签 <html> <body style="font-famliy:arial"> <img src="1.jp ...
- HDU 2502 月之数(二进制,规律)
月之数 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submis ...
- 2017广东工业大学程序设计竞赛初赛 题解&源码(A,水 B,数学 C,二分 D,枚举 E,dp F,思维题 G,字符串处理 H,枚举)
Problem A: An easy problem Description Peter Manson owned a small house in an obscure street. It was ...
- RMQ算法
1. 概述 RMQ(Range Minimum/Maximum Query),即区间最值查询,是指这样一个问题:对于长度为n的数列A,回答若干询问RMQ(A,i,j)(i,j<=n),返回数列A ...
- 利用Selenium+PhantomJS 实现截图
using OpenQA.Selenium; using OpenQA.Selenium.PhantomJS; using System; using System.Drawing; using Sy ...