Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 397|回复: 0

[默认分类] Java创建线程的两个方法

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-12 17:05:27 | 显示全部楼层 |阅读模式
    [url=http://www.cnblogs.com/lavenderone/arcHive/2011/09/23/2186603.HTML][/url]



      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. }
    11. class MutliThread extends Thread{
    12.         private int ticket=100;//每个线程都拥有100张票
    13.         MutliThread(String name){
    14.                 super(name);//调用父类带参数的构造方法
    15.         }
    16.         public void run(){
    17.                 while(ticket>0){
    18.                         System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
    19.                 }
    20.         }
    21. }
    复制代码
      
       
       程序中定义一个线程类,它扩展了Thread类。利用扩展的线程类在MutliThreadDemo类的主方法中创建了三个线程对象,并通过start()方法分别将它们启动。
      从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。但是结果显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较少,票迟一些卖完。
      可见,利用扩展Thread类创建的多个线程,虽然执行的是相同的代码,但彼此相互独立,且各自拥有自己的资源,互不干扰。
      (2)通过实现Runnable接口来创建多线程
       
      
      
    1. public class MutliThreadDemo2 {
    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. }
    14. class MutliThread implements Runnable{
    15.         private int ticket=100;//每个线程都拥有100张票
    16.         private String name;
    17.         MutliThread(String name){
    18.                 this.name=name;
    19.         }
    20.         public void run(){
    21.                 while(ticket>0){
    22.                         System.out.println(ticket--+" is saled by "+name);
    23.                 }
    24.         }
    25. }
    复制代码
      
      由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和(1)结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
      可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
       
      由于这三个线程也是彼此独立,各自拥有自己的资源,即100张电影票,因此程序输出的结果和例4.2.1的结果大同小异。均是各自线程对自己的100张票进行单独的处理,互不影响。
      可见,只要现实的情况要求保证新建线程彼此相互独立,各自拥有资源,且互不干扰,采用哪个方式来创建多线程都是可以的。因为这两种方式创建的多线程程序能够实现相同的功能。
      (3)通过实现Runnable接口来实现线程间的资源共享
       现实中也存在这样的情况,比如模拟一个火车站的售票系统,假如当日从A地发往B地的火车票只有100张,且允许所有窗口卖这100张票,那么每一个窗口也相当于一个线程,但是这时和前面的例子不同之处就在于所有线程处理的资源是同一个资源,即100张车票。如果还用前面的方式来创建线程显然是无法实现的,这种情况该怎样处理呢?看下面这个程序,程序代码如下所示:
       
      
      
    1. public class MutliThreadDemo3 {
    2.         public static void main(String [] args){
    3.                 MutliThread m=new MutliThread();
    4.                 Thread t1=new Thread(m,"Window 1");
    5.                 Thread t2=new Thread(m,"Window 2");
    6.                 Thread t3=new Thread(m,"Window 3");
    7.                 t1.start();
    8.                 t2.start();
    9.                 t3.start();
    10.         }
    11. }
    12. class MutliThread implements Runnable{
    13.         private int ticket=100;//每个线程都拥有100张票
    14.         public void run(){
    15.                 while(ticket>0){
    16.                         System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
    17.                 }
    18.         }
    19. }
    复制代码
      
       结果正如前面分析的那样,程序在内存中仅创建了一个资源,而新建的三个线程都是基于访问这同一资源的,并且由于每个线程上所运行的是相同的代码,因此它们执行的功能也是相同的。
      可见,如果现实问题中要求必须创建多个线程来执行同一任务,而且这多个线程之间还将共享同一个资源,那么就可以使用实现Runnable接口的方式来创建多线程程序。而这一功能通过扩展Thread类是无法实现的,读者想想看,为什么?
      实现Runnable接口相对于扩展Thread类来说,具有无可比拟的优势。这种方式不仅有利于程序的健壮性,使代码能够被多个线程共享,而且代码和数据资源相对独立,从而特别适合多个具有相同代码的线程去处理同一资源的情况。这样一来,线程、代码和数据资源三者有效分离,很好地体现了面向对象程序设计的思想。因此,几乎所有的多线程程序都是通过实现Runnable接口的方式来完成的。
       
       
       

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-3-29 00:33 , Processed in 0.377960 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表