转自: http://blog.csdn.net/sunguangran/article/details/6069317

非常感谢原作者,整理的这么详细。

在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接口的子类。

【转载】JAVA中线程的两种实现方法-实现Runnable接口和继承Thread类的更多相关文章

  1. java中线程分两种,守护线程和用户线程。

    java中线程分为两种类型:用户线程和守护线程. 通过Thread.setDaemon(false)设置为用户线程: 通过Thread.setDaemon(true)设置为守护线程. 如果不设置次属性 ...

  2. 线程入门之实现Runnable接口和继承Thread类

    线程的2种使用方式:实现Runnable接口和继承Thread类 1.实现Runnable接口 实现Runnable接口,必须实现run方法,也是Runnable接口中的唯一一个方法 class Ru ...

  3. Java创建线程的两种方法

    大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...

  4. java创建线程的两种方式及源码解析

    创建线程的方式有很多种,下面我们就最基本的两种方式进行说明.主要先介绍使用方式,再从源码角度进行解析. 继承Thread类的方式 实现Runnable接口的方式 这两种方式是最基本的创建线程的方式,其 ...

  5. java中创建多线程两种方式以及实现接口的优点

    多线程创建方式有两种 创建线程的第一种方式.继承Thread类 1.继承Thread类 2.重写Thread类中的run方法--目的将自定义代码存储在run方法.让线程执行3.调用线程的start() ...

  6. Java新建线程的两种方式

    Java新建线程有两种方式,一种是通过继承Thread类,一种是实现Runnable接口,下面是新建线程的两种方式. 我们假设有个竞赛,有一个选手A做俯卧撑,一个选手B做仰卧起坐.分别为两个线程: p ...

  7. Java创建线程的第二种方式:实现runable接口

    /*需求:简单的卖票程序多个窗口买票 创建线程的第二种方式:实现runable接口 *//*步骤1.定义类实现Runable接口2.覆盖Runable接口中的run方法    将线程要运行的代码存放在 ...

  8. java中线程的几种状态和停止线程的方法

    1.线程的状态图 需要注意的是:线程调用start方法是使得线程到达就绪状态而不是运行状态 2.停止线程的两种方法 1)自然停止:线程体自然执行完毕 2)外部干涉:通过线程体标识 1.线程类中定义线程 ...

  9. java中线程的三种实现方式

    一下记录下线程的3中实现方式:Thread,Runnable,Callable 不需要返回值时,建议使用Runnable:有返回值时建议使用Callable 代码如下所示: package com.f ...

随机推荐

  1. Java中,由this关键字引发的问题

    很久之前一直有一个疑问,最近重新翻了遍JVM的书,才算是终于有所顿悟.问题如下: 被自己遗忘的问题 package org.hanyan.test.testClass; public class T3 ...

  2. cmake编译选项

    1 需求 现在已经有一个cmake工程,我想要添加-O0 -g,生成gdb的调试信息和不进行代码优化. 也就是说,我该怎样修改CFLAGS和CPPFLAGS? 2 在project后面添加 set(C ...

  3. PHP判断是手机端访问还是PC端访问网站

    Mobile_Detect 是一个轻量级的开源移动设备(手机)检测的 PHP Class, 它使用 User-Agent 中的字符串,并结合 HTTP Header,来检测移动设备环境. 这个设备检测 ...

  4. 我的Android进阶之旅------>Android中查看应用签名信息

    一.查看自己的证书签名信息 如上一篇文章<我的Android进阶之旅------>Android中制作和查看自定义的Debug版本Android签名证书>地址:http://blog ...

  5. 【转载】Java中使用Jedis操作Redis

    1 package com.test; 2 3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.Li ...

  6. vue+django前后端分析解决csrf token问题

    vue-resource post数据 参考:https://www.cnblogs.com/linxizhifeng/p/8995077.html 阅读django CsrfViewMiddlewa ...

  7. python 文件格式为 txt 转换成 csv 格式

    1  txt 文件的读取 open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=Tr ...

  8. uwsgi+nginx项目上线

    一.基础环境配置 1.Linux安装配置     1.设置IP地址 [root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 ...

  9. Linux基础系列:常用命令(2)

    作业一: 1) 新建用户natasha,uid为1000,gid为555,备注信息为“master” groupadd -g 555 natasha useradd -u 1000 -g 555 -c ...

  10. Python 3 文件和字符编码

     一.文件: 打开文件的模式有: r,只读模式(默认). w,只写模式. 不可读,不存在则创建:存在则删除内容 a,追加模式. 可读,不存在则创建:存在则只追加内容 "+"表示可以 ...