`
冰诺莫语
  • 浏览: 8524 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Java中创建线程的两种方式

 
阅读更多

线程(thread)是进程中某个单一顺序的控制流。也被称为轻量进程(lightweight processes)。计算机科学术语,指运行中的程序的调度单位。通俗的来说,线程就是程序执行的线索,每一个线程都是一条在执行的线索,线索可以有很多条,即多线程。

下面我们来看一下Java中创建线程的两种方式:

1.继承Thread类,重写父类的run()方法。

2.实现Runnable接口,实现借口中的run()方法。

下面我们通过简短的代码来看一下。

继承Thread类:

package com.alex.lip.iteye;
/**
 * 继承Thread类,并且重写父类Thread中的run()方法。
 */
public class SubThread extends Thread{

 @Override
 public void run() {
  // 写一个死循环,使线程一直处于运行状态
  while (true) {
   try {
    // 线程睡眠500ms
    Thread.sleep(500);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   //打印输出当前线程的线程名
   System.out.println("This class extends Thread====1:" + Thread.currentThread().getName());
   // 在此例中,可以使用this代表当前线程的对象,不建议使用。
   System.out.println("This class extends Thread====2:" + this.getName());
  }
 }
}

实现Runnable接口:

package com.alex.lip.iteye;
/**
 * 实现Runnable接口,实现其中的run方法
 *
 */
public class ThreadExtendsRunnable implements Runnable{

 @Override
 public void run() {
  // 写一个死循环,使线程一直处于运行状态
  while (true) {
   try {
    // 线程睡眠500ms
    Thread.sleep(500);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
   //打印输出当前线程的线程名
   System.out.println("This class implements Runnable====1:" + Thread.currentThread().getName());
  }
 }
}

测试类:

package com.alex.lip.iteye;

public class TestThread {

 public static void main(String[] args) {
  //=============继承Thread独享===
  // 创建一个SubThread对象赋予thread1
  Thread thread1 = new SubThread();
  // 启动该线程
  thread1.start();
  
  //=============实现Runnable接口
  // 首先创建一个ThreadExtendsRunnable对象,赋给target
  Runnable target = new ThreadExtendsRunnable();
  // 将Runnbale对象target当做参数传给Thread的有参构造方法
  Thread thread2 = new Thread(target);
  // 启动线程
  thread2.start();
 }
}

输出结果:

This class extends Thread====1:Thread-0
This class extends Thread====2:Thread-0
This class implements Runnable====1:Thread-1
This class extends Thread====1:Thread-0
This class extends Thread====2:Thread-0
This class implements Runnable====1:Thread-1

注:由于是死循环输出,故输出结果很多,在此仅截取一部分结果为例。

 

下面我们通过源代码来看一下,为什么会有这两种创建线程的方式。大家都知道,线程是通过start()方法启动的,但是线程的执行都在run()方法内,所以我们来看一下Thread类中的run()方法,代码如下:

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

在run方法中,就简短的两行代码,如果target不为null,则执行target.run()方法。通过查看源代码可以发现,target是一个Runnbale对象。那么在创建线程的过程中也就有了这两种方式,1.继承Thread类,重写run()方法,那么在调用start()后就会调用到子类中重写的run()方法,如果子类没有重写run()方法,那么就会调用父类的run()方法,代码如上,此时即会调用到实现Runnbale接口的对象中实现的的run()方法。所以就会有这两种方式来创建线程。但是此时会有一个疑问,假如这两种方式都存在会怎么样呢?我们看如下的例子。

  new Thread(new Runnable() {
   @Override
   public void run() {
    while (true) {
     try {
      Thread.sleep(500);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println("Runnable===1:" + Thread.currentThread().getName());
    }
   }
  }) {
   public void run() {
    while (true) {
     try {
      Thread.sleep(500);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
     System.out.println("Thread===1:" + Thread.currentThread().getName());
    }
   };
  }.start();

运行结果如下:

Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0
Thread===1:Thread-0

如果子类中不重写run()方法,则同上面举过的Runnable的例子,这里就不再举例。

注:个人水平有限,如果文中存在不正确地方,希望大家指出,谢谢!

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics