博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java中Runnable和Thread的区别
阅读量:6972 次
发布时间:2019-06-27

本文共 3667 字,大约阅读时间需要 12 分钟。

hot3.png

在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口;Thread类是在java.lang包中定义的。一 个类只要继承了Thread类同时覆写了本类中的run()方法就可以实现多线程操作了,但是一个类只能继承一个父类,这是此方法的局限。

例子:

package org.thread.demo;  class MyThread extends Thread{      private String name;      public MyThread(String name) {          super();          this.name = name;      }      public void run(){          for(int i=0;i<10;i++){              System.out.println("线程开始:"+this.name+",i="+i);          }      }  }  package org.thread.demo;  public class ThreadDemo01 {      public static void main(String[] args) {          MyThread mt1=new MyThread("线程a");          MyThread mt2=new MyThread("线程b");          mt1.run();          mt2.run();      }  }

但是,此时结果很有规律,先第一个对象执行,然后第二个对象执行,并没有相互运行。在JDK的文档中可以发现,一旦调用start()方法,则会通过JVM找到run()方法。下面启动start()方法启动线程:

package org.thread.demo;  public class ThreadDemo01 {      public static void main(String[] args) {      MyThread mt1=new MyThread("线程a");      MyThread mt2=new MyThread("线程b");      mt1.start();      mt2.start();      }  }

这样程序可以正常完成交互式运行。那么为啥非要使用start();方法启动多线程呢?

在JDK的安装路径下,src.zip是全部的java源程序,通过此代码找到Thread中的start()方法的定义,可以发现此方法中使用了 private native void start0();其中native关键字表示可以调用操作系统的底层函数,那么这样的技术成为JNI技术(java Native Interface)

Runnable接口

在实际开发中一个多线程的操作很少使用Thread类,而是通过Runnable接口完成。

public interface Runnable{      public void run();  }

例子:

package org.runnable.demo;  class MyThread implements Runnable{      private String name;      public MyThread(String name) {          this.name = name;      }    public void run(){          for(int i=0;i<100;i++){              System.out.println("线程开始:"+this.name+",i="+i);          }      }  }

但是在使用Runnable定义的子类中没有start()方法,只有Thread类中才有。此时观察Thread类,有一个构造方法:public Thread(Runnable targer)此构造方法接受Runnable的子类实例,也就是说可以通过Thread类来启动Runnable实现的多线程。(start()可以协调系统的资源):

package org.runnable.demo;  import org.runnable.demo.MyThread;  public class ThreadDemo01 {      public static void main(String[] args) {          MyThread mt1=new MyThread("线程a");          MyThread mt2=new MyThread("线程b");          new Thread(mt1).start();          new Thread(mt2).start();      }  }

两种实现方式的区别和联系:

在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:

  • 避免点继承的局限,一个类可以继承多个接口。

  • 适合于资源的共享

以卖票程序为例,通过Thread类完成:

package org.demo.dff;  class MyThread extends Thread{      private int ticket=10;      public void run(){          for(int i=0;i<20;i++){              if(this.ticket>0){                  System.out.println("卖票:ticket"+this.ticket--);              }          }      }  }

下面通过三个线程对象,同时卖票:

package org.demo.dff;  public class ThreadTicket {      public static void main(String[] args) {          MyThread mt1=new MyThread();          MyThread mt2=new MyThread();          MyThread mt3=new MyThread();          mt1.start();//每个线程都各卖了10张,共卖了30张票          mt2.start();//但实际只有10张票,每个线程都卖自己的票          mt3.start();//没有达到资源共享      }  }

如果用Runnable就可以实现资源共享,下面看例子:

package org.demo.runnable;  class MyThread implements Runnable{      private int ticket=10;      public void run(){          for(int i=0;i<20;i++){              if(this.ticket>0){                  System.out.println("卖票:ticket"+this.ticket--);              }          }      }  }  package org.demo.runnable;  public class RunnableTicket {      public static void main(String[] args) {          MyThread mt=new MyThread();          new Thread(mt).start();//同一个mt,但是在Thread中就不可以,如果用同一          new Thread(mt).start();//个实例化对象mt,就会出现异常          new Thread(mt).start();      }  }

虽然现在程序中有三个线程,但是一共卖了10张票,也就是说使用Runnable实现多线程可以达到资源共享目的。

Runnable接口和Thread之间的联系:

public class Thread extends Object implements Runnable

发现Thread类也是Runnable接口的子类。

转载于:https://my.oschina.net/u/992626/blog/354451

你可能感兴趣的文章
netbase3监控mysql
查看>>
java开发常见的一些问题总结
查看>>
百度地图利用DrivingRoute做轨迹回放
查看>>
Nginx if 条件判断
查看>>
联想y460 +centos6.4 64位 开启无线热点Ap
查看>>
Htc t528w root教程
查看>>
Python 标准库中的装饰器
查看>>
Linux下查看和添加环境变量
查看>>
spark2.x由浅入深深到底系列六之RDD java api详解四
查看>>
jmeter+ant+jenkins
查看>>
Linux基础命令---grep
查看>>
Linux基础命令---cancel取消打印任务
查看>>
理解ORACLE数据库字符集
查看>>
Top Coder算法题目浏览器
查看>>
为SharePoint 2016 配置SQL 2016的always on 模式(二)
查看>>
PHP 选择排序法
查看>>
使用css3做立体效果!
查看>>
CIO的管理经
查看>>
ssh故障解决一例
查看>>
linux学习笔记-第十一课-shell基础
查看>>