Java提供了线程类Thread来创建多线程的程序。其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象。每个Thread对象描述了一个单独的线程。要产生一个线程,有两种方法:

    ◆需要从Java.lang.Thread类派生一个新的线程类,重载它的run()方法;
    ◆实现Runnalbe接口,重载Runnalbe接口中的run()方法。

  为什么Java要提供两种方法来创建线程呢?它们都有哪些区别?相比而言,哪一种方法更好呢?

  在Java中,类仅支持单继承,也就是说,当定义一个新的类的时候,它只能扩展一个外部类.这样,如果创建自定义线程类的时候是通过扩展 Thread类的方法来实现的,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能。因此,如果自定义类必须扩展其他的类,那么就可以使用实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性。

  还有一点最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享.

  1、通过扩展Thread类来创建多线程

  假设一个影院有三个售票口,分别用于向儿童、成人和老人售票。影院为每个窗口放有100张电影票,分别是儿童票、成人票和老人票。三个窗口需要同时卖票,而现在只有一个售票员,这个售票员就相当于一个CPU,三个窗口就相当于三个线程。通过程序来看一看是如何创建这三个线程的。

 1 public class MutliThreadDemo {
2 public static void main(String[] args) {
3 MutliThread m1=new MutliThread("Window 1");
4 MutliThread m2=new MutliThread("Window 2");
5 MutliThread m3=new MutliThread("Window 3");
6 m1.start();
7 m2.start();
8 m3.start();
9 }
10 }
 1 public class MutliThread extends Thread {
2 private int ticket=100;//每个线程都拥有100张票
3
4 public MutliThread (){}
5 public MutliThread (String name){
6 super(name);
7 }
8
9 @Override
10 public void run() {
11 while(ticket>0){
12 System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
13 }
14 }
15 }

  程序中定义一个线程类,它扩展了Thread类。利用扩展的线程类在MutliThreadDemo类的主方法中创建了三个线程对象,并通过start()方法分别将它们启动。

从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。但是结果

显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较

少,票迟一些卖完。

  可见,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。

  2、通过实现Runnable接口来创建多线程

 1 public class MutliThreadDemo {
2 public static void main(String[] args) {
3 MutliThread m1=new MutliThread("Window 1");
4 MutliThread m2=new MutliThread("Window 2");
5 MutliThread m3=new MutliThread("Window 3");
6 Thread t1=new Thread(m1);
7 Thread t2=new Thread(m2);
8 Thread t3=new Thread(m3);
9 t1.start();
10 t2.start();
11 t3.start();
12 }
13 }
 1 public class MutliThread implements Runnable{
2 private int ticket=100;//每个线程都拥有100张票
3 private String name;
4 MutliThread(String name){
5 this.name=name;
6 }
7 public void run(){
8 while(ticket>0){
9 System.out.println(ticket--+" is saled by "+name);
10 }
11 }
12 }

  由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和 1 结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。

  可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。

  3、通过实现Runnable接口来实现线程间的资源共享

  现实中也存在这样的情况,比如模拟一个火车站的售票系统,假如当日从A地发往B地的火车票只有100张,且允许所有窗口卖这100张票,那么每一个窗口也相当于一个线程,但是这时和前面的例子不同之处就在于所有线程处理的资源是同一个资源,即100张车票。如果还用前面的方式来创建线程显然是无法实现的,这种情况该怎样处理呢?看下面这个程序,程序代码如下所示:

 1 public class MutliThreadDemo {
2 public static void main(String[] args) {
3 MutliThread m=new MutliThread();
4 Thread t1=new Thread(m);
5 Thread t2=new Thread(m);
6 Thread t3=new Thread(m);
7 t1.start();
8 t2.start();
9 t3.start();
10 }
11 }
1 public class MutliThread implements Runnable{
2 private int ticket=100;//每个线程都拥有100张票
3 public void run(){
4 while(ticket>0){
5 System.out.println(ticket--+" is saled by "+Thread.currentThread());
6 }
7 }
8 }

  结果正如前面分析的那样,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。

  可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的,读者想想看,为什么?

  实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。

转自:http://www.cnblogs.com/gw811/archive/2012/10/15/2724882.html

Java 创建线程的两种方法的更多相关文章

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

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

  2. java创建线程的四种方法

    第一种:  通过继承Thread类创建线程 第二种: 通过实现Runnable接口创建线程 这两种早已烂记于心,这里就不作过多的介绍, 主要介绍其源码 Thread类 implements Runna ...

  3. java创建线程的三种方法

    这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...

  4. Java创建线程的两个方法

    Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...

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

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

  6. 进程和创建线程的两种方法(threading.Thread)

    进程 如QQ 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理, 网络接口的调用等,进程就是各种资源管理的集合 线程:是操作系统最小的调度单位,是一串指令的结合 进程 要操作 ...

  7. Java线程(一)——创建线程的两种方法

    Thread 和 Runnable Java程序是通过线程执行的,线程在程序中具有独立的执行路径.当多条线程执行时,它们之间的路径可以不同,例如,一条线程可能在执行switch的一个case语句,另一 ...

  8. 区分JAVA创建线程的几种方法

    1. start()和run()       通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行.然后 通过此Thread类调用方法run()来完成其运行操 ...

  9. Java 创建线程的3种方法及各自优势

    1. 继承 Thread 类,然后调用 start 方法. class MyThread extends Thread { //重写run方法,线程运行后,跑的就是run方法 public void ...

随机推荐

  1. 使用RestTemplate post方式提交表单数据

    HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_FORM_URLENCODE ...

  2. Nuske vs Phantom Thnook

    Nuske vs Phantom Thnook Time limit : 4sec / Memory limit : 256MB Score : 700 points Problem Statemen ...

  3. Linux 装JDK

    1.查看当前系统有没有装jdk java -version 2.看看有没有安装包 rpm -qa | grep java 3.卸载OpenJDK $>rpm -e --nodeps tzdata ...

  4. js实现文字列表无缝向上滚动

    body{font-size:12px} #demo{overflow:hidden; height:80px; width:280px; margin:90px auto; position:rel ...

  5. 3.5.基于STC89C52+MC20的短信远程控制开关LCD1602显示

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  6. Http1.0和Http1.1的主要区别

    1.HTTP 1.1支持长连接(PersistentConnection)和请求的流水线(Pipelining)处理 HTTP 1.0规定浏览器与服务器只保持短暂的连接,浏览器的每次请求都需要与服务器 ...

  7. github代码托管

    下载github客户端软件 1)  官网下载help.github.com 2)  百度搜索,一般用于windows7以前的系统 安装github软件 按照软件提示安装即可.不过,博主倾向使用命令行工 ...

  8. python——异常

    一.什么是异常 1.错误 从软件方面来说,错误是语法或是逻辑上的.错误是语法或是逻辑上的. 语法错误指示软件的结构上有错误,导致不能被解释器解释或编译器无法编译.这些些错误必须在程序执行前纠正. 当程 ...

  9. Protobuf支持 pointf

    Protobuf支持 pointf序列化 加入:ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(System.Drawing.PointF), fa ...

  10. POJ 3468 A Simple Problem with Integers 【线段树】

    题目链接 http://poj.org/problem?id=3468 思路 线段树 区间更新 模板题 在赋初始值的时候,按点更新区间就可以 AC代码 #include <cstdio> ...