全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

java  多线程的三种构建方法

java  多线程的三种构建方法

继承Thread类创建线程类

public class Thread extends Object implements Runnable
  1. 定义Thread类的子类,并重写其run()方法
  2. 创建Thread子类的实例,即创建了线程对象
  3. 调用线程对象的start()方法启动线程
public class FirstThread extends Thread {
  public void run(){
    for(int i=0;i<100;i++){
      /*
       * Thread类已经继承了Object
       * Object类创建了name选项 并且有其getName(),setName()方法
       * 在继承Thread的类里面使用时只需要用this引用
      */
      System.out.println(this.getName()+" "+i);
    }
  }

  public static void main(String[] args) {
    for(int i=0;i<100;i++){
      System.out.println(Thread.currentThread().getName()+" "+i);
      if(i==20){
        new FirstThread().start();
        new FirstThread().start();
      }
    }
  }

}

Thread类已经继承了Object

Object类创建了name选项 并且有其getName(),setName()方法

在继承Thread的类里面使用时只需要用this引用

上面两个副线程和主线程随机切换,又因为使用的是继承Thread的类所以两个副线程不能共享资源

start()方法调用后并不是立即执行多线程代码,而是使得该线程编程可运行状态,什么时候运行是由操作系统决定的

实现Runnable接口创建线程类

public Thread() 
public Thread(Runnable target) 
public Thread(Runnable target,String name)
  • 定义Runnable接口的实现类,并重写该接口的run()方法
  • 创建Runnable实现类的实例,并以此作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
public class SecondThread implements Runnable {
  public void run(){
    for(int i=0;i<100;i++){
      System.out.println(Thread.currentThread().getName()+" "+i);
    }
  }

  public static void main(String[] args) {
    for(int i=0;i<100;i++){
      System.out.println(Thread.currentThread().getName()+" "+i);

      if(i==20){
        SecondThread st=new SecondThread();
        //通过new Thread(target,name)创建线程
        new Thread(st,"新线程1").start();
        new Thread(st,"新线程2").start();
      }
    }
  }
}

上面的结果是两个副线程和主线程随机切换,但是并没有共享资源,因为他们根本没有能用来共享的资源。

start()方法调用后并不是立即执行多线程代码,而是使得该线程编程可运行状态,什么时候运行是由操作系统决定的
继承Thread类和创建Runnable接口的共享资源详解

在只有可以用来共享的资源时候,也就是同用一个实例化对象。两个创建方式在共享资源时才会有所区别,否则它们都不会共享资源共享资源通常用private static 修饰符来修饰。

class Thread1 extends Thread{ 
  private int count=5; 
  private String name; 
  public Thread1(String name) { 
    this.name=name; 
  } 
  public void run() { 
    for (int i = 0; i < 5; i++) { 
      System.out.println(name + "运行 count= " + count--); 
      try { 
        sleep((int) Math.random() * 10); 
      } catch (InterruptedException e) { 
        e.printStackTrace(); 
      } 
    } 

  } 
} 

public class Main { 

  public static void main(String[] args) { 
    Thread1 mTh1=new Thread1("A"); 
    Thread1 mTh2=new Thread1("B"); 
    mTh1.start(); 
    mTh2.start(); 

  } 

} 

B运行 count= 5 
A运行 count= 5 
B运行 count= 4 
B运行 count= 3 
B运行 count= 2 
B运行 count= 1 
A运行 count= 4 
A运行 count= 3 
A运行 count= 2 
A运行 count= 1

正是因为有了private int count=5;一句才有了共享资源,但这是继承Thread类的子类,并不能共享资源

class Thread2 implements Runnable{ 
  private int count=15; 
  public void run() { 
     for (int i = 0; i < 5; i++) { 
       System.out.println(Thread.currentThread().getName() + "运行 count= " + count--); 
        try { 
          Thread.sleep((int) Math.random() * 10); 
        } catch (InterruptedException e) { 
          e.printStackTrace(); 
        } 
      } 

  } 

} 
public class Main { 

  public static void main(String[] args) { 

    Thread2 my = new Thread2(); 
      new Thread(my, "C").start();//同一个mt,但是在Thread中就不可以,如果用同一个实例化对象mt,就会出现异常   
      new Thread(my, "D").start(); 
      new Thread(my, "E").start(); 
  } 

} 

C运行 count= 15 
D运行 count= 14 
E运行 count= 13 
D运行 count= 12 
D运行 count= 10 
D运行 count= 9 
D运行 count= 8 
C运行 count= 11 
E运行 count= 12 
C运行 count= 7 
E运行 count= 6 
C运行 count= 5 
E运行 count= 4 
C运行 count= 3 
E运行 count= 2

同样的正是因为有了private int count=15这个共同的实例化对象,实现Runnable的类才可以共享资源

那么为什么继承Thread类的子类实现Runable接口的类在共享资源时有区别呢?

因为Java中只能支持单继承,单继承特点意味着只能有一个子类去继承 而Runnabl接口后可以跟好多类,便可以进行多个线程共享一个资源的操作

使用Callable和Future创建线程

Callable怎么看起来都像Runnable接口的增强版,Callable有一个call()方法相当于Runnable的run()方法,但是功能却更加强大:

call()方法可以有返回值
call()方法可以声明抛出异常

Callable接口有泛型限制,Callable接口里的泛型形参类型与call()方法的返回值类型相同。 而且Callable接口是函数式接口,因此可使用Lambda表达式创建Callable对象 Runnable接口也是函数式接口,因此也可以使用Lambda表达式创建Runnable对象

  1. 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,再创建Callable实现类的实例
  2. 使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法
  3. 使用FutureTask类对象作为Thread对象的target创建并启动新线程
  4. 调用FutureTask对象的get()方法来获得子线程结束后的返回值
public class ThirdThread implements Callable<Integer> {
  public Integer call(){
    int i=0;
    for(;i<100;i++){
      System.out.println(Thread.currentThread().getName()+" "+i);
    }
    return i;
  }

  public static void main(String[] args){
    ThirdThread tt=new ThirdThread();
    FutureTask<Integer> task=new FutureTask<>(tt);
    Thread t=new Thread(task,"有返回值的线程");
    for(int i=0;i<100;i++){
      System.out.println(Thread.currentThread().getName()+" "+i);
      if(i==20){
        t.start();
      }
    }
    try{
      System.out.println("返回值是:"+task.get());
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}

使用Lambda表达式的Callable和Future创建的线程

public class ThirdThread{
  public static void main(String[] args){
    ThirdThread tt=new ThirdThread();
    //先使用Lambda表达式创建Callable<Integer>对象
    //使用FutureTask封装Callable对象
    FutureTask<Integer> task=new FutureTask<Integer>((Callable<Integer>)()->{
      int i=0;
      for(;i<100;i++){
        System.out.println(Thread.currentThread().getName()+"的循环变量i的值:"+i);
      }
      return i;
    });

    for(int i=0;i<100;i++){
      System.out.println(Thread.currentThread().getName()+"的循环变量i的值:"+i);
      if(i==20){
        new Thread(task,"有返回值的线程").start();
      }
    }
    try{
      System.out.println("子线程的返回值"+task.get());
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}

如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


# java  # 多线程  # 多线程的实现方法  # 多线程的三种方法  # java 中多线程生产者消费者问题详细介绍  # java多线程编程学习(线程间通信)  # Java多线程的用法详细介绍  # java多线程学习笔记之自定义线程池  # Java基于Socket实现简单的多线程回显服务器功能示例  # java 多线程Thread与runnable的区别  # java多线程学习之死锁的模拟和避免(实例讲解)  # java多线程之火车售票系统模拟实例  # Java Socket实现多线程通信功能示例  # Java多线程用法的实例详解  # 子类  # 返回值  # 什么时候  # 是由  # 只需  # 要用  # 重写  # 正是因为  # 有一个  # 的是  # 这是  # 运行状态  # 操作系统  # 就会  # 一句  # 多个  # 如有  # 不可以  # 继承了 


相关文章: 怀化网站制作公司,怀化新生儿上户网上办理流程?  宝盒自助建站智能生成技巧:SEO优化与关键词设置指南  智能起名网站制作软件有哪些,制作logo的软件?  无锡营销型网站制作公司,无锡网选车牌流程?  建站主机选哪种环境更利于SEO优化?  如何通过VPS搭建网站快速盈利?  建站之星价格显示格式升级,你的预算足够吗?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  简易网站制作视频教程,使用记事本编写一个简单的网页html文件?  上海制作企业网站有哪些,上海有哪些网站可以让企业免费发布招聘信息?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  宝塔新建站点报错如何解决?  青岛网站设计制作公司,查询青岛招聘信息的网站有哪些?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  如何在Windows环境下新建FTP站点并设置权限?  教程网站设计制作软件,怎么创建自己的一个网站?  武汉网站如何制作,黄黄高铁武穴北站途经哪些村庄?  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  佛山网站制作系统,佛山企业变更地址网上办理步骤?  免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?  C++如何编写函数模板?(泛型编程入门)  外汇网站制作流程,如何在工商银行网站上做外汇买卖?  如何用低价快速搭建高质量网站?  实例解析Array和String方法  seo网站制作优化,网站SEO优化步骤有哪些?  如何将凡科建站内容保存为本地文件?  如何快速完成中国万网建站详细流程?  早安海报制作网站推荐大全,企业早安海报怎么每天更换?  如何快速生成ASP一键建站模板并优化安全性?  建站主机空间推荐 高性价比配置与快速部署方案解析  全景视频制作网站有哪些,全景图怎么做成网页?  商务网站制作工程师,从哪几个方面把握电子商务网站主页和页面的特色设计?  浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?  html制作网站的步骤有哪些,iapp如何添加网页?  c++怎么用jemalloc c++替换默认内存分配器【性能】  如何在IIS中配置站点IP、端口及主机头?  nginx修改上传文件大小限制的方法  网站按钮制作软件,如何实现网页中按钮的自动点击?  微课制作网站有哪些,微课网怎么进?  重庆网站制作公司哪家好,重庆中考招生办官方网站?  北京网站制作网页,网站升级改版需要多久?  建站之星2.7模板快速切换与批量管理功能操作指南  如何快速搭建高效可靠的建站解决方案?  如何在服务器上三步完成建站并提升流量?  如何选择高效便捷的WAP商城建站系统?  东莞专业制作网站的公司,东莞大学生网的网址是什么?  如何选择高效可靠的多用户建站源码资源?  如何用y主机助手快速搭建网站?  建站之星安装需要哪些步骤及注意事项?  移民网站制作流程,怎么看加拿大移民官网? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。