java线程——三种创建线程的方式
前言
线程,英文Thread。在java中,创建线程的方式有三种:
1、Thread
2、Runnable
3、Callable
在详细介绍下这几种方式之前,我们先来看下Thread类和Runnable接口。
Runnable接口
接口中只有一个run()方法,等待实现类去实现。
-
package java.lang;
-
@FunctionalInterface
-
public interface Runnable {
-
-
public abstract void run();
-
}
Thread类
该类实现了Runnable接口,也提供了很多其他的方法,如yield(),join()等
-
package java.lang;
-
public
-
class Thread implements Runnable {
-
//获取当前线程
-
public static native Thread currentThread();
-
public static native void yield();
-
//一系列的构造函数
-
public Thread(Runnable target, String name) {
-
init(null, target, name, 0);
-
}
-
public Thread(ThreadGroup group, String name) {
-
init(group, null, name, 0);
-
}
-
/*调用该方法时,jvm会调用run方法
-
*Causes this thread to begin execution; the Java Virtual Machine
-
* calls the run method of this thread.
-
*/
-
public synchronized void start() {
-
-
if (threadStatus != 0)
-
throw new IllegalThreadStateException();
-
-
group.add(this);
-
-
boolean started = false;
-
try {
-
start0();
-
started = true;
-
} finally {
-
try {
-
if (!started) {
-
group.threadStartFailed(this);
-
}
-
} catch (Throwable ignore) {
-
-
}
-
}
-
}
-
-
}
一、实现Runnable接口
-
public class i_Runnable {
-
-
/**
-
* 主线程main方法
-
* @param args
-
*/
-
public static void main(String[] args) {
-
for (int i = 0; i < 100; i++) {
-
System.out.println(Thread.currentThread().getName() + "====" + i);
-
if (i == 20) {
-
RunnableThreadTest rtt = new RunnableThreadTest();
-
//子线程
-
new Thread(rtt, "new Thread[1]====").start();
-
//new Thread(rtt, "新线程2").start();
-
}
-
}
-
-
}
-
/**
-
* RunnableThreadTest实现Runnable接口
-
* @author YANG
-
*
-
*/
-
static class RunnableThreadTest implements Runnable {
-
private int i;
-
-
@Override
-
public void run() {
-
for (i = 0; i < 100; i++) {
-
System.out.println(Thread.currentThread().getName() + " " + i);
-
}
-
-
}
-
-
}
-
}
执行结果:
注意:
** 执行结果只截取了部分内容。
** 如果RunnableThreadTest类前不加static,会报错No enclosing instance of type i_Runnable is accessible. Must qualify the allocation with
an enclosin。因为只有内部类修饰为静态时,才可以在静态类方法(main方法)中调用该类的成员变量和方法。
二、继承Thread类
-
public class a_Thread {
-
public static void main(String[] args) {
-
Runner1 r=new Runner1();
-
r.start(); //已经有thread 不需要new,直接调用start即可。
-
-
-
for (int i = 0; i < 100; i++) {
-
System.out.println("main Thread:"+i);
-
}
-
}
-
-
//Runner1继承Thread类,重写run方法
-
static class Runner1 extends Thread{
-
@Override
-
public void run() {
-
-
for (int i = 0; i < 100; i++) {
-
System.out.println("Runner1:"+i);
-
}
-
-
}
-
-
}
-
}
思考:能不能将上面的r.start(); 改为 r.run();
分析:换成run()方法之后,就变成了普通的方法调用,只有一个主线程,没有子线程。
执行结果:为了方便显示,我们将循环次数改为10。
-
Runner1:0
-
Runner1:1
-
Runner1:2
-
Runner1:3
-
Runner1:4
-
Runner1:5
-
Runner1:6
-
Runner1:7
-
Runner1:8
-
Runner1:9
-
main Thread:0
-
main Thread:1
-
main Thread:2
-
main Thread:3
-
main Thread:4
-
main Thread:5
-
main Thread:6
-
main Thread:7
-
main Thread:8
-
main Thread:9
三、实现Callable接口
前面两种方式是传统的线程技术中的内容,第三种方式Callable和Future是jdk1.5之后新增的。我们先来补充点东西,看看这种方式与之前的方式有什么联系。
-
//实现Callable接口
-
public class j_CallableTest implements Callable<String> {
-
public static void main(String[] args) {
-
j_CallableTest test=new j_CallableTest();
-
FutureTask<String> ft=new FutureTask<>(test);
-
-
for (int i = 0; i < 100; i++) {
-
System.out.println(Thread.currentThread().getName()+" i的值为="+i);
-
if(i==20){
-
new Thread(ft,"子线程").start();
-
}
-
}
-
}
-
-
//重写call方法
-
@Override
-
public String call() throws Exception {
-
int i = 0;
-
String reString = "";
-
for (; i < 100; i++) {
-
reString = Thread.currentThread().getName() + " " + i;
-
System.out.println(reString);
-
}
-
return reString;
-
}
-
}
从上面可以看到,new Thread的方式还是用的public Thread(Runnable target, String name); 说明FutureTask也是Runnable类型的,他们之间的关系可以从下图中看出来。
那么,使用Callable和Future的方式有什么特点呢?
我们从他们的定义来看,Callable接口中只有一个方法,返回值为V。前两种方式都是返回void。
-
@FunctionalInterface
-
public interface Callable<V> {
-
/**
-
* Computes a result, or throws an exception if unable to do so.
-
*
-
* @return computed result
-
* @throws Exception if unable to compute a result
-
*/
-
V call() throws Exception;
-
}
小结:
1、接口实现更灵活,java不支持多继承。在这方面,Runnable和Callable更有优势。
2、返回值问题。Runnable和Thread都不能有返回值,但Callable可以,而且支持多种类型的数据。
就这两点来看,新增的Callable和Future的实现方式优势十分明显啊。但是追到原理,其实这三种都可以归结为一种方式。
java线程——三种创建线程的方式的更多相关文章
- 【Java 线程的深入研究1】Java 提供了三种创建线程的方法
Java 提供了三种创建线程的方法: 通过实现 Runnable 接口: 通过继承 Thread 类本身: 通过 Callable 和 Future 创建线程. 1.通过实现 Runnable 接口来 ...
- JavaScript DOM三种创建元素的方式
三种创建元素的方式: document.write() element.innerHTML document.createElement() 初始HTML内容: <button>btn&l ...
- java线程(1)——三种创建线程的方式
前言 线程,英文Thread.在java中,创建线程的方式有三种: 1.Thread 2.Runnable 3.Callable 在详细介绍下这几种方式之前,我们先来看下Thread类和Runnabl ...
- Java多线程学习总结--线程概述及创建线程的方式(1)
在Java开发中,多线程是很常用的,用得好的话,可以提高程序的性能. 首先先来看一下线程和进程的区别: 1,一个应用程序就是一个进程,一个进程中有一个或多个线程.一个进程至少要有一个主线程.线程可以看 ...
- 线程系列1--Java创建线程的几种方式及源码分析
线程--创建线程的几种方式及源码分析 开始整理下线程的知识,感觉这块一直是盲区,工作中这些东西一直没有实际使用过,感觉也只是停留在初步的认识.前段时间一个内推的面试被问到,感觉一脸懵逼.面试官说,我的 ...
- Servlet三种创建方式
直接实现 Servlet 接口不太方便,所以 Servlet 又内置了两个 Servlet 接口的实现类(抽象类),分别为 GenericServlet 和 HttpServlet,因此,创建 Ser ...
- Django多对多表的三种创建方式,MTV与MVC概念
MTV与MVC MTV模型(django): M:模型层(models.py) T:templates V:views MVC模型: M:模型层(models.py) V:视图层(views.py) ...
- Django-多对多关系的三种创建方式-forms组件使用-cookie与session-08
目录 表模型类多对多关系的三种创建方式 django forms 组件 登录功能手写推理过程 整段代码可以放过来 forms 组件使用 forms 后端定义规则并校验结果 forms 前端渲染标签组件 ...
- Js基础知识4-函数的三种创建、四种调用(及关于new function()的解释)
在js中,函数本身属于对象的一种,因此可以定义.赋值,作为对象的属性或者成为其他函数的参数.函数名只是函数这个对象类的引用. 函数定义 // 函数的三种创建方法(定义方式) function one( ...
随机推荐
- 学习TF:《TensorFlow机器学习实战指南》中文PDF+英文PDF+代码
从实战角度系统讲解TensorFlow基本概念及各种应用实践.真实的应用场景和数据,丰富的代码实例,详尽的操作步骤,带你由浅入深系统掌握TensorFlow机器学习算法及其实现. <Tensor ...
- U-BOOT概述及源码分析(一)
嵌入式Linux系统从软件角度通常可以分为以下4个层次: 引导加载程序 | Linux内核 | 文件系统 | 用户应用程序 嵌入式Linux系统中典型分区结构: 正常启动过程中,Bootloader首 ...
- python全栈_day01
计算机容量 1位 = 1bit 8bit = 1byte = 1字节 1024bytes = 1kbytes =1KB 1024个字符,小文档 ,几百k可以表示一张图片 1024KB ...
- C# textBox控件只允许为数字和小数点并且提取出这个数字
一. textBox控件实现只允许为数字和小数点 如下图所示,在textBox控件框内输入只能是 要在textBox控件属性设置按键按下的事件触发,如下图所示: 二.源代码 textBox控件只允许为 ...
- HTML5吃豆豆游戏开发实战(一)使用Canvas绘制游戏主角
近期在学习HTML5.爱因斯坦曾说过,"最好的学习就是自己去经历". 于是.我想在学习HTML5的同一时候.做一款简单的小游戏,这样学习起来也会非常有趣的.我想做的是曾经小时候玩儿 ...
- Python Web框架Tornado的异步处理代码演示样例
1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ...
- Hadoop-2.6.0上的C的API訪问HDFS
在通过Hadoop-2.6.0的C的API訪问HDFS的时候,编译和执行出现了不少问题,花费了几天的时间,上网查了好多的资料,最终还是把问题给攻克了 參考文献:http://m.blog.csdn.n ...
- 【Android】利用自己定义View的重绘实现拖动移动,获取组件的尺寸
以下利用一个app来说明怎样利用自己定义View的重绘实现拖动移动.获取组件的尺寸. 例如以下图,触摸拖动,或者轻轻点击屏幕都能移动图片.假设碰到文字,则会弹出提示. 这里是利用自己定义View的重绘 ...
- hq-源码编译
这里编译整个项目的基本格式是 ./mk + 平台名 +项目名_客户名 +mmm +new 例如 ./mk hq6735_65c_b1k_l1 al811_doov mmm new 编译单个模块 ./m ...
- MVC和MTV设计模式
1.MVC MVC最初是由施乐公司旗下的帕罗奥多研究中心中的一位研究人员给 smalltalk语言发明的一中软件设计模式. MVC概述:MVC全名是ModelViewController,是模型(mo ...