对于很多想学习java的人来说,经常听别人说线程难,其实真正理解了线程后,一点都不会觉得线程难,这里我为大家梳理下线程的创建方式吧.

一.线程的创建方式有三种

1.继承Thread类

2.实现Runnable接口

3.实现Callable接口(返回结果并且可能抛出异常的任务).

如果采用实现Callable接口接口的方式,返回结果并且可能抛出异常的任务,不利于开发,这里就不给大家介绍了.这里咋们主要说说采用继承Thread类和实现Runnable接口的方式来创建线程.

1.继承Thread类的方式

Java使用java.lang.Thread类代表线程,所有的线程对象都必须是Thread类或其子类的实例。每个线程的作用是完成一定的任务,实际上就是执行一段程序流即一段顺序执行的代码。Java使用线程执行体来代表这段程序流。Java中通过继承Thread类来创建启动多线程的步骤如下:

  1. 定义Thread类的子类,并重写该类的run()方法,该run()方法的方法体就代表了线程需要完成的任务,因此把run()方法称为线程执行体。

  2. 创建Thread子类的实例,即创建了线程对象

  3. 调用线程对象的start()方法来启动该线程

代码如下:

测试类:

/*
1)定义类继承Thread,重写run方法
2)创建线程对象
3)进行调用线程的start方法进行开启线程 */
public class Demo01 {
public static void main(String[] args) { MyThread m = new MyThread();
m.start(); for (int i = 0; i < 100; i++) {
System.out.println("小强:" + i);
} }
}

创建类来实现Thread

public class MyThread extends Thread {
@Override
public void run() {
//多线程处理的任务
for (int i = 0; i < 100; i++) {
System.out.println("旺财:" + i);
}
}
}

看了上面的代码,你可能会问,线程对象是如何创建的,线程里面有哪些方法呢?下面就来说说怎么创建线程对象.

通过查看API我们看到了lang包下的Thread类,是非抽象的,还有构造方法,那是不是就是可以直接用Thread类的构造方法来创建对象呢?答案是:不可以!!!

记住:

Thread类的构造方法不是为创建线程而定的,是给子类使用的!!!

线程常用的方法:
1. public String getName():获取当前线程名称。
2. public void start():导致此线程开始执行; Java虚拟机调用此线程的run方法。
3. public void run():此线程要执行的任务在此处定义代码。
4. public static void sleep(long millis):使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
5. public static Thread currentThread():返回对当前正在执行的线程对象的引用。

线程的执行步骤:线程执行,开启了线程,JVM调用其run方法来执行任务。

public class MyThread2 extends Thread {
public MyThread2(){
super(); // public Thread()
} public MyThread2(String name) {
super(name);/// public Thread(String name)
} @Override
public void run() {
//如果没有给线程起名:默认 Thread-x
String name = getName(); //获取线程的名字
System.out.println(name +"线程执行起来");
}
}

测试类

public class Demo02 {
public static void main(String[] args) {
//Thread直接创建对象,Thread(),Thread(String name)
Thread mt1 = new Thread();
mt1.start(); MyThread2 mt2 = new MyThread2();
mt2.start(); MyThread2 mt3 = new MyThread2("小强");
mt3.start(); //public static Thread currentThread():返回当前方法运行的线程对象
Thread thread = Thread.currentThread();
String name = thread.getName();
System.out.println("main方法执行的线程名字: " + name); //public static void sleep(long mills)
for (int i = 0; i < 10; i++) {
System.out.println(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} }
}

Thread类API查询:

2.实现Runnable接口

首先我们来看看API是怎么说的

由API中的介绍,我们采用java.lang.Runnable也是非常常见的一种,我们不用继承Thread类,只需要重写run方法即可。

  1. public Thread(Runnable target):分配一个带有指定目标新的线程对象。

  2. public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。

一般使用步骤:
1)先创建任务【Runnable的对象】
2)借助含有Runnable参数的Thread构造方法,进行创建线程
3)调用线程的start方法开启线程

public class Demo01 {
public static void main(String[] args) {
Runnable runnable = new MyRunnable();
//1. public Thread(Runnable target):分配一个带有指定目标新的线程对象。
Thread mth1 = new Thread(runnable);
mth1.start(); //2. public Thread(Runnable target,String name):分配一个带有指定目标新的线程对象并指定名字。 Thread mth2 = new Thread(runnable, "旺财");
mth2.start(); //3. 匿名内部类实现
Runnable target = new Runnable() {
@Override
public void run() {
Thread thread = Thread.currentThread();
String name = thread.getName(); System.out.println(name+"线程执行run方法【匿名内部类实现】");
}
}; new Thread(target).start();
new Thread(target,"旺财").start(); }
}

通过实现Runnable接口,使得该类有了多线程类的特征。run()方法是多线程程序的一个执行目标。所有的多线程代码都在run方法里面。Thread类实际上也是实现了Runnable接口的类。

在启动的多线程的时候,需要先通过Thread类的构造方法Thread(Runnable target) 构造出对象,然后调用Thread对象的start()方法来运行多线程代码。

小结

多线程代码都是通过调用Thread的start()方法来运行的。因此,不管是继承Thread类还是实现Runnable接口来实现多线程,最终还是通过Thread的对象的API来控制线程的,熟悉Thread类的API是进行多线程编程的基础。

Runnable对象仅仅作为Thread对象的target,Runnable实现类里包含的run()方法仅作为线程执行体。而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法。

3.Thread和Runnable的区别

如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

总结:

实现Runnable接口比继承Thread类所具有的优势:

  1. 适合多个相同的程序代码的线程去共享同一个资源。

  2. 可以避免java中的单继承的局限性。

  3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。

  4. 线程池只能放入实现Runnable或Callable类线程,不能直接放入继承Thread的类。

扩充:在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进程。

几种创建线程方式Thread类和Runnable接口的更多相关文章

  1. 【多线程】创建线程方式二:实现Runnable接口

    创建线程方式二:实现Runnable接口 代码示例: /** * @Description 实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法 * ...

  2. 多线程, Thread类,Runnable接口

    多线程 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程.一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序. 单线程程序:即,若有多个任务只能依次执 ...

  3. 使用Thread类和Runnable接口实现多线程的区别

    使用Thread类和Runnable接口实现多线程的区别 先看两种实现方式的步骤: public class ThreadDemo{ public static void main(String[] ...

  4. Thread类与Runnable接口的深入理解

    Thread类与Runnable接口的深入理解1.Thread类实现了Runnable接口,实现run方法,其中target参数对应的就是一个Runnable接口的实现类 @Override publ ...

  5. 探Java多线程Thread类和Runnable接口之间的联系

    首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说  有如下两种情 ...

  6. 多线程-----Thread类与Runnable接口的区别

    第一个继承Thread类来实现多线程,其实是相当于拿出三件事即三个卖早餐10份的任务分别分给三个窗口,他们各做各的事各卖各的早餐各完成各的任务,因为MyThread继承Thread类,所以在newMy ...

  7. Java多线程和并发(三),Thread类和Runnable接口

    目录 1.Thread和Runnable接口 三.Thread类和Runnable接口 1.Thread和Runnable接口

  8. 多线程----Thread类,Runnable接口,线程池,Callable接口,线程安全

    1概念 1.1进程 进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能. 任务管理器中: 1.2线程 线程是进程中的一个执行单元 ...

  9. 7种创建线程方式,你知道几种?线程系列Thread(一)

    前言 最近特别忙,博客就此荒芜,博主秉着哪里不熟悉就开始学习哪里的精神一直在分享着,有着扎实的基础才能写出茁壮的代码,有可能实现的逻辑有多种,但是心中必须有要有底哪个更适合,用着更好,否则则说明我们对 ...

随机推荐

  1. C++设计模式之State模式

    这里有两个例子: 1.https://www.cnblogs.com/wanggary/archive/2011/04/21/2024117.html 2.https://www.cnblogs.co ...

  2. VC FTP服务器程序分析(二)

    上面讲到了CClientThread类,打开这个类的实现,这个类实现了4个函数.依次分析: 1.InitInstance   其说明如下:InitInstance必须被重载以初始化每个用户界面线程的新 ...

  3. Vue 中的受控与非受控组件

    Vue 中的受控与非受控组件 熟悉 React 的开发者应该对"受控组件"的概念并不陌生,实际上对于任何组件化开发框架而言,都可以实现所谓的受控与非受控,Vue 当然也不例外.并且 ...

  4. vmware9虚拟机通过NAT上网方式设置

    vmware虚机上网的网络连接方式有bridge.NAT.Host-only等,如果对这个不了解的可以学习这篇文章http://wangchunhai.blog.51cto.com/225186/38 ...

  5. os、sys和shutil模块

    运行环境:python3 OS模块:os 模块提供了一个统一的操作系统的接口函数 下面的path指路径的意思 os.stat(file) #查询文件属性操作 os.sep #取代操作系统特定的路径分隔 ...

  6. opencv直方图该怎么画

    图像直方图是反映图像中像素分布特性的统计表,一般显示如下: 其中横坐标代表的是图像像素的种类,或者说是灰度级,纵坐标代表的是每一级灰度下像素数或者该灰度级下像素数在所有图像总像素数总所占的百分比. 直 ...

  7. I.MX6 U-boot imxotp MAC address 写入

    /***************************************************************************** * I.MX6 U-boot imxotp ...

  8. 开发微信小程序心得

    元旦过后,根据公司的项目要求,项目组开始集体研究小程序,在这想谈点个人开发小程序心得,首先就是需要看小程序的文档,如同很多框架一样,不可能一上来就能动手敲代码(大神除外),其次就是不能一直单纯的看,因 ...

  9. Android应用开发完全退出程序的通用方法

    在开发一个android应用时,有可能有N个Activity,而在每个Activity里的菜单里有个"退出程序"菜单,这里就要完全退出程序了,所以今天给大家分享的是Android应 ...

  10. String、StringBuffer和StringBuilder有什么区别?

    1. String 类 String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间.String a = "a&quo ...