精华内容
下载资源
问答
  • 一、线程实现的两种方式 1、... 2、实现Runnable接口,成为线程任务类。二、Thread类部分源码 * @author unascribed * @see Runnable * @see Runtime#exit(int) * @see #run() * @see #stop() * @since JDK1...

    一、线程实现的两种方式

        1、继承Thread成为线程类;

        2、实现Runnable接口,成为线程任务类。

    二、Thread类部分源码

     
    * @author  unascribed
     * @see     Runnable
     * @see     Runtime#exit(int)
     * @see     #run()
     * @see     #stop()
     * @since   JDK1.0
     */
    public
    class Thread implements Runnable {
        /* Make sure registerNatives is the first thing <clinit> does. */
        private static native void registerNatives();
        static {
            registerNatives();
        }
    
        /* What will be run. */
        private Runnable target;        //##########################################333
            。。。。。。。
     * @param  target
     *         the object whose {@code run} method is invoked when this thread
     *         is started. If {@code null}, this classes {@code run} method does
     *         nothing.
     */
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);   //########初始化方法,不用考虑#########3
    } 
    
           。。。。。。。
    * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }
    
            。。。。。

    从源码上分析,如果直接new Thread().start(),会怎样呢?

    答案是什么都没做,run()方法相当于没用。但是如果设置了runnable线程任务类,会跳转到任务类的run()。

    三、代码说明

    package com.steve.threads;
    /**
     * @Author Loujitao
     * @Date 2018/6/14
     * @Time  16:22
     * @Description:
     * 线程多用接口,而不是内部类。有几下几个原因:
     * 1、thread自身是runnable接口的实现类;如果线程类里面设置线程任务类,优先执行thread累里的run()
     * 2、继承为单继承,接口能多实现。复用性接口较优
     */
    public class TwoThreads {
    
        public static void main(String[] args) {
            //问题1:Thread是Runnable的实现类,重写了run方法。
            // 加载的时候会先找下面的run1;
            //如果没有重写的run的话,会找Thread的元run方法,里面调用的是Runnable的run3
            new Thread(new Runnable() {
                        @Override       //run3
                        public void run() {
                            System.out.println("这是Runnable的run方法!");
                        }
                    }
                ){
                @Override     //run1   这里重写了,会覆盖掉源码里的run(),即那个相当于跳转功能的方法。
                public void run() {
                    System.out.println("这是线程自身的run方法!");
                }
            }.start();
            //--------------手动分割线--------------------
            new Thread(new Runnable() {
                @Override       //run3
                public void run() {
                    System.out.println("这是Runnable的run方法!");
                }
            }
            ){
                 //这次没有重写Thread自身的run()
            }.start();
    
            //问题2:多实现优于多继承,大概是这样。具体实现就不写了,下面代码不能执行
    //        MyThreeds threed1=new MyThreeds();
    //        MyThreeds threed2=new MyThreeds();
    //        MyThreeds threed3=new MyThreeds();
    
    //       Runnable runnable1= new MyThreeds2();
    //                runnable1=new MyThreeds3();
    //                runnable1=new MyThreeds4();
    //        Thread thread1=new Thread(runnable1);
        }
    
    //继承方式的线程类
        class MyThreeds extends Thread{
            @Override
            public void run() {
                long i=System.currentTimeMillis();
                System.out.println("name:"+Thread.currentThread().getName()+"开始执行!");
                while (System.currentTimeMillis()-i<10000){
                    //空循环10s  Thread.sleep(10s);
                }
                System.out.println("name:"+Thread.currentThread().getName()+"执行结束!");
            }
        }
    //接口实现类方式的线程任务类
        class MyThreeds2 implements Runnable{
            @Override
            public void run() {
                long i=System.currentTimeMillis();
                System.out.println("name2:"+Thread.currentThread().getName()+"开始执行!");
                while (System.currentTimeMillis()-i<10000){
                    //空循环10s  Thread.sleep(10s);
                }
                System.out.println("name2:"+Thread.currentThread().getName()+"执行结束!");
            }
        }
    
    
    }
    

    代码说明:因为Thread自身实现了runnable接口,自身也是Runnable的实现类。只不过它自身的run(),没有实际意义,只能转调用,构造函数中设置进来的另一个Runnable实现类的run()。

    但是如果是Thread的子类的话,会重写run(),并在其中实现业务代码。将父类run()的跳转功能覆盖掉。




    展开全文
  • 1:通过继承Thread类的方式,可以完成多线程的建立。...只有对该类进行额外的功能扩展,java就提供了一个接口Runnable。这个接口中定义了run方法,其实run方法的定义就是为了存储多线程要运行的代码。 所以,
    1:通过继承Thread类的方式,可以完成多线程的建立。但是这种方式有一个局限性,如果一个类已经有了自己的父类,就不可以继承Thread类,因为java单继承的局限性。
    
    可是该类中的还有部分代码需要被多个线程同时执行。这时怎么办呢?
    只有对该类进行额外的功能扩展,java就提供了一个接口Runnable。这个接口中定义了run方法,其实run方法的定义就是为了存储多线程要运行的代码。
    所以,通常创建线程都用第二种方式。
    因为实现Runnable接口可以避免单继承的局限性。


    2:其实是将不同类中需要被多线程执行的代码进行抽取。将多线程要运行的代码的位置单独定义到接口中。为其他类进行功能扩展提供了前提。
    所以Thread类在描述线程时,内部定义的run方法,也来自于Runnable接口。
     
    实现Runnable接口可以避免单继承的局限性。而且,继承Thread,是可以对Thread类中的方法,进行子类复写的。但是不需要做这个复写动作的话,只为定义线程代码存放位置,实现Runnable接口更方便一些。所以Runnable接口将线程要执行的任务封装成了对象。
    展开全文
  • 主要大家详细介绍了如何使用Runnable实现数据共享,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • android demo,使用Runnable和Handler的特性实现每个3s的定时器
  • Runnable使用

    千次阅读 2020-10-04 12:33:30
    提示:推荐使用Runnable对象,因为Java单继承的局限性 参考代码 //创建线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法 public class Demo03 implements Runnable...

    Runnable

    1. 定义MyRunnable类实现Runnable接口

    2. 实现run()方法,编写线程执行体。

    3. 创建线程对象,调用start()方法启动线程。

      提示:推荐使用Runnable对象,因为Java单继承的局限性

    参考代码

    //创建线程方式二:实现Runnable接口,重写run方法,执行线程需要丢入Runnable接口实现类,调用start方法
    public class Demo03 implements Runnable {
    
        @Override
        public void run() {
            //run方法线程体
            for (int i = 0; i < 10; i++) {
                System.out.println("run方法");
            }
        }
    
        public static void main(String[] args) {
            //创建Runnable接口的实现类对象
            Demo03 d3 = new Demo03();
            //创建线程对象,通过线程对象来开启我们的线程
            
    //        Thread thread = new Thread(d3);
      //      thread.start();  //简写:new Thread(d3).start();
            new Thread(d3).start();
    
            for (int i = 0; i < 1000; i++) {
                System.out.println("Runnable接口");
            }
        }
    }
    
    

    实例(网图下载)

    //Thread和Runnable使用相同的run()方法和下载器
    import org.apache.commons.io.FileUtils;
    
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    
    //需要架包:commons-io.jar
    
    //练习Runnable,实现多线程同步下载图片
    public class Demo02 implements Runnable { //继承Thread:extends Thread
    
        private String url; //网络图片地址
        private String name; //保存的文件名
    
        //构造器
        public Demo02(String url, String name) {
            this.url = url;
            this.name = name;
        }
    
        @Override
        public void run() {
            WebDownloader webDownloader = new WebDownloader();
            webDownloader.downloader(url, name);
            System.out.println("下载了文件名为:" + name);
        }
    
    
        public static void main(String[] args) {
            Demo02 d1 = new Demo02("https://img-home.csdnimg.cn/images/20201001020546.jpg", "1.jpg");
            Demo02 d2 = new Demo02("https://img-home.csdnimg.cn/images/20201001020546.jpg", "2.jpg");
            Demo02 d3 = new Demo02("https://img-home.csdnimg.cn/images/20201001020546.jpg", "3.jpg");
    
            //使用Thread
    //      d1.start();
    //      d2.start();
    //      d3.start();
    
            //使用Runnable
            new Thread(d1).start();
            new Thread(d2).start();
            new Thread(d3).start();
        }
    }
    
    //下载器
    class WebDownloader {
        //下载方法
        public void downloader(String url, String name) {
            try {
                FileUtils.copyURLToFile(new URL(url),new File(name));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("IO异常,downloader方法出现问题");
            }
        }
    
    }
    

    总结

    1. 继承Thread类

      • 子类继承Thread类具备多线程能力
      • 启动线程:子类对象.start()
      • 不建议使用:避免OOP单继承局限性
    2. 实现Runnable接口

      • 实现接口Runnable具有多线程能力。
      • 启动线程:传入目标对象 + Thread对象.start()
      • 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用
      //一份资源
      Demo demo = new Demo();
      
      //多个代理
      new Thread(demo, "***").start();
      new Thread(demo, "**").start();
      new Thread(demo, "*").start();
      
    展开全文
  • 本篇文章介绍了,java中使用Runnable接口创建线程的方法。需要的朋友参考下
  • 有了Thread,为什么还要有Runnable? 1、为多继承提供可能。 对于类继承,java只允许单继承模式,如果你需要设计一个类既继承业务类拥有某个业务类功能,又继承线程对象Thread类具有多线程的功能,那么Thread类就...

    有了Thread,为什么还要有Runnable?
    1、为多继承提供可能。
    对于类继承,java只允许单继承模式,如果你需要设计一个类既继承业务类拥有某个业务类功能,又继承线程对象Thread类具有多线程的功能,那么Thread类就无法满足你的要求。这时候就要选择Runnable。更多的接口优于抽象类的内容可参考《Effect Java》中的第16条原则,这里不赘述。

    2、实现数据的共享。
    首先我们知道,Thread线程对象调用run()方法是采用回调的机制。其次,每个Thread线程对象只能调用一次start方法启用一个线程。因此,把数据放在Thread对象中,并不能被多个线程所共享。

    例:

    class T extends Thread {
        Object o;
        public void run() {......}
    }
    
    T t = new T();
     



    实例t所包含的数据对象o只能被实例t共享,当调用t.start()时,只有启用的线程能访问这个数据,即“一个数据实例对应一个线程”。

    一种改进方法是从外部传入数据

    class T extends Thread {
        Object o;
    
        public T(Object o) {
            this.o = o;
        }
    
        public void run() {......}
    }
    
     


    这样我们就可以生成一个对象并传给多个Thread对象,实现多线程操作一个数据。

    当然java为我们提供了Runnable接口,就很好的解决了这个问题。我们把要操作的数据封装入Runnable的实现类中,然后将Runnable实例传入多个Thread对象中,就可以实现一个对象数据在多个线程的共享了。

    Class R implements Runnable {
        Object o;
     
        public void run() {......}
    }
    
    Runnable r = new R();
    Thread t1 = new Thread(r);
    Thread t2 = new Thread(r);
    t1.start();
    t2.start();
     

     

    展开全文
  • 大家都知道Runnable和Callable接口都可以作为其他线程执行的任务,但是Runnable接口的run方法没有返回值,而Callable接口的call方法有返回值,...该Demo解压、导入到开发环境即可,测试入口test包下的MainTest.java
  • 使用runnable的注意事项

    千次阅读 2019-06-23 23:55:04
    我在线程中对数据库进行操作需要引入mapper,如果直接在runnbable的实现类中@Autowired引入会发现mapper空 解决方法: 1.有参构造声明,从外面引入.比如像beanName 的引入 2.从容器中获取已经声明的mapper 第一种...
  • 为什么通过实现Runnable接口的方式可以实现多线程内的资源共享 解决方法: 现在举例子说明一下: public static void main(String[] args) { Meal meal= new Meal(10); //假如现在有10个套餐 //Person1...
  • android handler runnable使用实例(关键是内部run中停止)
  • 实现Runnable接口的类必须使用Thread类的实例才能创建线程,通过Runnable接口创建线程分为以下两步
  • Java通过Executors提供四种线程池,分别: 1、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需求,可以灵活回收空闲线程,若无可回收则新建线程。 2、newFixedThreadPool创建一个定长线程池...
  • 在了解线程的基本概念后,在介绍其他...Runnable为非Thread子类的类提供了一种激活方式,通过实例化某个Thread实例并将自身作为运行。 如果只想重写run()方法,而不重写其他的Thread方法,那么应使用Runnable接口。 /
  • Runnable使用方法

    千次阅读 2016-10-31 15:11:08
    class ThreadTest implements Runnable{ private int ticket = 10; public void run(){ while(true){ if(ticket > 0){ System.out.println(Thread.currentThread().getName() + " is saling ticket" + ticket-...
  • 主要介绍了详解Java中多线程异常捕获Runnable的实现的相关资料,希望通过本文能帮助到大家,让大家理解掌握这样的知识,需要的朋友可以参考下
  • 主要介绍了Java向Runnable线程传递参数方法实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 使用Runnable接口实现线程的方法

    千次阅读 2018-08-05 13:29:05
    Runnable接口实现线程的方法主要有两点好处: ...(推荐使用这种方法创建线程) 具体详细请看下面的例子:   public class TheadDeno {  public static void main(String[] args) {  ...
  • 主要介绍了Java中Thread 和Runnable的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。
  • Runnable 和 Callable 有什么区别

    千次阅读 2019-05-13 17:12:54
    Runnable 和 Callable 有什么区别? 主要区别 Runnable 接口 run 方法无返回值;Callable 接口 call 方法有返回值,支持泛型 Runnable 接口 run 方法只能抛出运行时异常,且无法捕获处理;Callable 接口 call ...
  • 为什么使用线程池而不使用new Thread(runnable).start();

    万次阅读 多人点赞 2019-02-19 10:36:54
    1、每次new Thread,新建对象性能差 ...Java通过Executors提供四种线程池,分别: 1、newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需求,可以灵活回收空闲线程,若无可回收则新建线...
  • 怎样使用Runnable和Thread实现多线程?

    千次阅读 2018-05-22 19:40:01
    什么是线程?可以这样理解:线程就像是赛道,每个赛道互不影响。但是我们一般的程序中都是顺序进行的,也就是一个赛道的跑完后才进行下个赛道。而多线程弥补了这一缺点,让多个赛道能够同时运作,因此大大加快了运行...
  • 主要大家详细介绍了java实现Runnable接口适合资源的共享,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 线程池的使用Runnable接口)

    千次阅读 2018-08-18 17:35:34
    class MyRunnable1 implements Runnable{ @Override public void run () { // TODO Auto-generated method stub System.out.println( "我要一个教练" ); try { Thread.sleep( 2000 ); } catch ...
  • 有时我们的系统需要进行一些比较耗时的操作,比如用户注册后要调用邮件服务器给用户发送个邮件,又比如上传一个大数据量的excel并导入到... 这里我们使用java线程池ExecutorService,首先在项目中添加如下配置类...
  • 主要大家详细介绍了Java多线程如何实现Runnable方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 主要介绍了Java使用Thread和Runnable的线程实现方法,结合实例形式对比分析了Java使用Thread和Runnable实现与使用线程的相关操作技巧,需要的朋友可以参考下
  • 使用Runnable接口实现线程

    千次阅读 2016-04-21 21:00:08
    使用Runnable接口实现线程本质上使用了静态代理 故重点有以下几步: 1.实现一个线程类并继承Runnable接口,重写runfangfa 2.使用时牢记静态代理的关键3点 一是创建真实角色 2是创建代理角色 3.代理角色.start() ...
  • 使用Runnable接口的方式创建线程

    千次阅读 2018-05-14 21:09:16
    (1)定义MyRunnable类实现java.lang.Runnable接口,并实现Runnable接口的run()方法,在run()方法中输出数据。 (2)创建线程对象。 (3)调用start()方法启动线程。package cn.run.test; //通过实现Runnable接口创建线程 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 593,639
精华内容 237,455
关键字:

为什么使用runnable