java 创建线程的方法总结

发布时间 - 2026-01-10 23:21:46    点击率:

java 创建线程

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

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

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

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

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

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

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

public class MutliThreadDemo {
  public static void main(String [] args){
    MutliThread m1=new MutliThread("Window 1");
    MutliThread m2=new MutliThread("Window 2");
    MutliThread m3=new MutliThread("Window 3");
    m1.start();
    m2.start();
    m3.start();
  }
}
class MutliThread extends Thread{
  private int ticket=100;//每个线程都拥有100张票
  MutliThread(String name){
    super(name);//调用父类带参数的构造方法
  }
  public void run(){
    while(ticket>0){
      System.out.println(ticket--+" is saled by "+Thread.currentThread().getName());
    }
  }
}

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

从结果可以看到,每个线程分别对应100张电影票,之间并无任何关系,这就说明每个线程之间是平等的,没有优先级关系,因此都有机会得到CPU的处理。但是结果显示这三个线程并不是依次交替执行,而是在三个线程同时被执行的情况下,有的线程被分配时间片的机会多,票被提前卖完,而有的线程被分配时间片的机会比较少,票迟一些卖完。

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

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


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

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

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

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

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

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

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


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

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

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

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

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# java  # 创建线程  # 线程创建的方法  # 两种创建线程方法对比  # Java 创建线程的两个方法详解及实例  # java 创建线程的几种方式  # Java创建线程的两种方式  # Java并发编程之创建线程  # java多线程编程之使用runnable接口创建线程  # java多线程编程之使用thread类创建线程  # java线程之用Thread类创建线程的方法  # java线程之使用Runnable接口创建线程的方法  # java创建线程的两种方法区别  # 多线程  # 多个  # 都是  # 自己的  # 这三个  # 自定义  # 的是  # 其他的  # 大同小异  # 这两种  # 来实现  # 方法来  # 就可以  # 卖完  # 这一  # 对自己的  # 是在  # 都有  # 很好  # 也就 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Windows10电脑怎么查看硬盘通电时间_Win10使用工具检测磁盘健康  Android okhttputils现在进度显示实例代码  HTML5段落标签p和br怎么选_文本排版常用标签对比【解答】  Laravel如何处理文件上传_Laravel Storage门面实现文件存储与管理  如何自定义建站之星网站的导航菜单样式?  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  三星、SK海力士获美批准:可向中国出口芯片制造设备  制作公司内部网站有哪些,内网如何建网站?  如何快速生成可下载的建站源码工具?  PHP正则匹配日期和时间(时间戳转换)的实例代码  Python文件异常处理策略_健壮性说明【指导】  详解Huffman编码算法之Java实现  深圳网站制作平台,深圳市做网站好的公司有哪些?  Swift中循环语句中的转移语句 break 和 continue  如何用已有域名快速搭建网站?  Laravel如何设置自定义的日志文件名_Laravel根据日期或用户ID生成动态日志【技巧】  利用JavaScript实现拖拽改变元素大小  如何在宝塔面板中创建新站点?  如何用PHP快速搭建高效网站?分步指南  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  免费网站制作appp,免费制作app哪个平台好?  Laravel怎么实现支付功能_Laravel集成支付宝微信支付  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  如何在 Go 中优雅地映射具有动态字段的 JSON 对象到结构体  javascript中的数组方法有哪些_如何利用数组方法简化数据处理  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  高端智能建站公司优选:品牌定制与SEO优化一站式服务  大型企业网站制作流程,做网站需要注册公司吗?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  HTML 中动态设置元素 name 属性的正确语法详解  Laravel如何清理系统缓存命令_Laravel清除路由配置及视图缓存的方法【总结】  java获取注册ip实例  Laravel如何实现本地化和多语言支持?(i18n教程)  Android使用GridView实现日历的简单功能  JavaScript如何操作视频_媒体API怎么控制播放  详解vue.js组件化开发实践  Python3.6正式版新特性预览  如何在IIS服务器上快速部署高效网站?  Laravel Eloquent模型如何创建_Laravel ORM基础之Model创建与使用教程  怎么用AI帮你设计一套个性化的手机App图标?  Laravel如何集成Inertia.js与Vue/React?(安装配置)  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  Laravel怎么使用Session存储数据_Laravel会话管理与自定义驱动配置【详解】  linux写shell需要注意的问题(必看)  Laravel怎么生成URL_Laravel路由命名与URL生成函数详解  Laravel怎么集成Log日志记录_Laravel单文件与每日日志配置及自定义通道【详解】  如何在香港免费服务器上快速搭建网站?  如何在 Pandas 中基于一列条件计算另一列的分组均值  Thinkphp 中 distinct 的用法解析  历史网站制作软件,华为如何找回被删除的网站?