1、通过实现Runnable接口线程创建

(1).定义一个类实现Runnable接口,重写接口中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。

(2).创建Runnable接口实现类的对象。

(3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象。(接口可以实现多继承)

(4).调用Thread对象的start()方法,启动线程

示例代码:

  1. <span style="font-size:16px;">package demo.thread;
  2. public class TreadDemo1 implements Runnable {
  3. private int countDown = 10;
  4. @Override
  5. // 在run方法中定义任务
  6. public void run() {
  7. while (countDown-- > 0) {
  8. System.out.println("#" + Thread.currentThread().getName() + "("
  9. + countDown + ")");
  10. }
  11. }
  12. public static void main(String[] args) {
  13. // Runnable中run方法是一个空方法,并不会产生任何线程行为,必须显式地将一个任务附着到线程上
  14. TreadDemo1 tt=new TreadDemo1();
  15. new Thread(tt).start();
  16. new Thread(tt).start();
  17. System.out.println("火箭发射前倒计时:");
  18. }
  19. }
  20. </span>

运行结果:

火箭发射前倒计时:
#Thread-1(8)
#Thread-1(7)
#Thread-1(6)
#Thread-1(5)
#Thread-1(4)
#Thread-1(3)
#Thread-1(2)
#Thread-1(1)
#Thread-1(0)
#Thread-0(9)

2、通过继承Thread类创建线程

(1).首先定义一个类去继承Thread父类,重写父类中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。
(2).直接创建一个ThreadDemo2类的对象,也可以利用多态性,变量声明为父类的类型。

(3).调用start方法,线程t启动,隐含的调用run()方法。

示例代码:

  1. <span style="font-size:16px;">package demo.thread;
  2. public class ThreadDemo2 extends Thread {
  3. private int countDown = 10;
  4. @Override
  5. // 在run方法中定义任务
  6. public void run() {
  7. while (countDown-- > 0) {
  8. System.out.println("#" + this.getName() + "(" + countDown + ")");
  9. }
  10. }
  11. public static void main(String[] args) {
  12. new ThreadDemo2().start();
  13. new ThreadDemo2().start();
  14. // 由于start方法迅速返回,所以main线程可以执行其他的操作,此时有两个独立的线程在并发运行
  15. System.out.println("火箭发射前倒计时:");
  16. }
  17. }
  18. </span>

运行结果:

#Thread-0(9)
#Thread-0(8)
#Thread-0(7)
#Thread-0(6)
#Thread-0(5)
#Thread-0(4)
#Thread-0(3)
#Thread-0(2)
#Thread-0(1)
#Thread-0(0)
火箭发射前倒计时:
#Thread-1(9)
#Thread-1(8)
#Thread-1(7)
#Thread-1(6)
#Thread-1(5)
#Thread-1(4)
#Thread-1(3)
#Thread-1(2)
#Thread-1(1)
#Thread-1(0)
3、两种方式的比较

首先分析两种方式的输出结果,同样是创建了两个线程,为什么结果不一样呢?

使用实现Runnable接口方式创建线程可以共享同一个目标对象(TreadDemo1 tt=new TreadDemo1();),实现了多个相同线程处理同一份资源。

然后再看一段来自JDK的解释:

Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。类必须定义一个称为run 的无参数方法。

设计该接口的目的是为希望在活动时执行代码的对象提供一个公共协议。例如,Thread 类实现了Runnable。激活的意思是说某个线程已启动并且尚未停止。

此外,Runnable 为非 Thread 子类的类提供了一种激活方式。通过实例化某个Thread 实例并将自身作为运行目标,就可以运行实现
Runnable 的类而无需创建 Thread 的子类。大多数情况下,如果只想重写run() 方法,而不重写其他
Thread 方法,那么应使用 Runnable 接口。这很重要,因为除非程序员打算修改或增强类的基本行为,否则不应为该类创建子类。

采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法。

java多线程总结一:线程的两种创建方式及优劣比较的更多相关文章

  1. java多线程总结:线程的两种创建方式及优劣比较

    1.通过实现Runnable接口线程创建 (1).定义一个类实现Runnable接口,重写接口中的run()方法.在run()方法中加入具体的任务代码或处理逻辑. (2).创建Runnable接口实现 ...

  2. 1.java多线程_实现线程的两种方式

    1.java多线程基本知识 1.1.进程介绍 不管是我们开发的应用程序,还是我们运行的其他的应用程序,都需要先把程序安装在本地的硬盘上.然后找到这个程序的启动文件, 启动程序的时候,其实是电脑把当前的 ...

  3. java多线程总结一:线程的两种创建方式及比较

    1.线程的概念:线程(thread)是指一个任务从头至尾的执行流,线程提供一个运行任务的机制,对于java而言,一个程序中可以并发的执行多个线程,这些线程可以在多处理器系统上同时运行.当程序作为一个应 ...

  4. Thread -线程的两种创建方式

    package cn.learn.thread.Thread; /* 实现Runnable必须重写run()方法,一般推荐用Runnable实现 */ public class RunnableImp ...

  5. [转载]Java线程的两种实现方式

    转载:http://baijiahao.baidu.com/s?id=1602265641578157555&wfr=spider&for=pc 前言 线程是程序的一条执行线索,执行路 ...

  6. 【转载】 Java中String类型的两种创建方式

    本文转载自 https://www.cnblogs.com/fguozhu/articles/2661055.html Java中String是一个特殊的包装类数据有两种创建形式: String s ...

  7. python 多进程的两种创建方式

    Python中使用线程有两种方式:函数或者用类来包装线程对象. 第一种---------函数 菜鸟教程的我没看懂,说说我自己懂的----看视频理解的 import time import thread ...

  8. String变量的两种创建方式

    在java中,有两种创建String类型变量的方式: String str01="abc";//第一种方式 String str02=new String("abc&qu ...

  9. java中多线程的两种创建方式

    一丶继承Thread类实现多线程 第一步:继承Thread类第二步:重写run()方法第三步:创建继承了Thread类的对象 , 调用start()方法启动. //线程创建方式一 : /* 第一步:继 ...

随机推荐

  1. linux中ctime,mtime,atime的区别

    st_atime Time when file data was last accessed. Changed by  the            following   functions:    ...

  2. hdu 2716 Message Decowding

    Message Decowding Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  3. UIViewController生命周期测试

    push进入  -[NaviRootVC viewWillDisappear:]  -[NextVC viewWillAppear:]  -[NextVC viewWillLayoutSubviews ...

  4. jq向上无缝滚动

    <!-- -------------摇奖排行榜--------------- --> <div class="Top_Record"> <div cl ...

  5. MFC 学习 之 状态栏的添加

    1.首先声明一个 CStatusBar  m_bar;//声明对象2.然后打开视图资源 String Table中添加两个字段值 3.创建了两个字段值以后,在OnintDialog() 所在的 .cp ...

  6. Linux下查看CPU型号,内存大小,硬盘空间命令

    1 查看CPU 1.1 查看CPU个数 # cat /proc/cpuinfo | grep "physical id" | uniq | wc -l 2 **uniq命令:删除重 ...

  7. zookeeper配置同步zookeeper编程

    分布式助手Zookeeper(四) kissyoudyb 2013-12-05 17:41 阅读:33 评论:0     分布式助手Zookeeper(三) kissyoudyb 2013-12-05 ...

  8. js上传文件获取客户端地址

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. Windows下python环境变量配置

    默认情况下,在windows下安装python之后,系统并不会自动添加相应的环境变量.此时不能在命令行直接使用python命令. 1. 首先需要在系统中注册python环境变量:假设python的安装 ...

  10. 文件和目录之设置用户ID和设置组ID

    与一个进程相关联的ID有6个或更多,它们如表4-4所示: 表4-4 与每个进程相关联的用户ID和组ID 实际用户ID                            我们实际上是谁 实际组ID ...