疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

创建Java线程的两种方式及区别


 

   

  1.线程和进程的区别

  并行:是多个任务在同一时间同时执行,例如多核计算机同时计算的任务可以理解为并行

  并发:从微观上看是多个任务抢占一个CPU从而执行自己的任务,轮流执行任务,但是如果遇到资源冲突的时候并没有从根本提高执行效率。但是提高了CPU的使用效率。

  前段时间在GitHub上的一幅图可以很好的阐述上面的概念非常形象

  图片名称

  2.Java中创建线程的两种方式

  1.第一种方式:直接继承Thread:

  public class Dog extends Thread {

  // 私有变量

  private int number;

  // 初始化乘法表上限数字

  public Dog(int number) {

  this.number = number;

  }

  //重写逻辑方法

  @Override

  public void run() {

  // 打印乘法表

  for (int i = 1; i <= number; i++) {

  for (int j = 1; j <= i; j++) {

  System.out.print(j + " * " + i + " = " + i * j + " ");

  }

  System.out.println();

  }

  }

  public static void main(String[] args) {

  Dog dog = new Dog(9);

  dog.start();//启动线程打印乘法表

  }

  }

  2.第二种方式:实现Runnable接口的方式

  public class Cat implements Runnable {

  private int number;

  public Cat(int number) {

  this.number = number;

  }

  //重写逻辑方法

  @Override

  public void run() {

  System.out.println("Current Thread :" + Thread.currentThread());

  for (int i = 0; i <= number; i++) {

  for (int j = 0; j <= i; j++) {

  System.out.print(i + " * " + j + " = " + i * j + " ");

  }

  System.out.println();

  }

  }

  public static void main(String[] args) {

  Thread task = new Thread(new Cat(9));

  task.start();

  }

  }

  对比以上两种方式可以发现:第一种方式继承Thread不能再继承其他父类,所以对于程序的扩展性不是很友好,但是可以通过this访问当前线程的信息。第二种方式继承Runnable接口,从设计角度来看比较灵活,Java是不支持多继承但是支持实现多个接口,这样就可以将这个缺点给克服了,如果要访问线程信息需要使用Thread.currentThread();方法。

  3.源码分析

  public class Thread implements Runnable {

  //关联Runnable接口

  private Runnable target;

  //线程逻辑方法

  public void run() {

  if (target != null) {

  target.run();

  }

  }

  }

  //线程接口

  public interface Runnable {

  //定义抽象的线程逻辑方法,

  public abstract void run();

  }

  上面的Thread类和Runnable接口是Java JDK中两个最重要的核心部分,继承Thread属于对JDK本身的系统类的扩展,而实现Runnable接口的方式属于实现一种标准。不管哪种方式JVM启动线程的过程中都将他们进行装载,只不过方式不一样而已。具体哪种方法比较好,当然第二种方式从设计方面比较优雅和灵活。