精华内容
下载资源
问答
  • runnable
    万次阅读
    2018-01-18 20:17:59

    Runnable


    概述

    • java version “1.8.0_131”
    • 多线程创建方式之一
    public class RunnableTest implements Runnable{
    
        // 实现 run() 
        public void run() {
            System.out.println("thread");
        }
    
        public static void main(String[] args) {
            RunnableTest test = new RunnableTest();
            // 线程启动由Thread负责
            Thread thread = new Thread(test);
            thread.start();
        }
    }
    • Runnable只有一个抽象的run()方法,此方法是在运行时由JVM调用,每一个运行期的Runnable实现类实例(包括Thread的子类,因为Thread亦是实现了Runnable接口)都对应于操作系统中的一个线程,所以说Java中的线程只是操作系统线程的一个映射,Java中线程的运行效率也不可能高于底层语言线程,因为Java中线程的创建和调用需要经过JVM,JVM再向下调用(JNI的方式与特定平台进行通信)

    类注释

    /**
     * The <code>Runnable</code> interface should be implemented by any
     * class whose instances are intended to be executed by a thread. The
     * class must define a method of no arguments called <code>run</code>.
     * <p>
     * This interface is designed to provide a common protocol for objects that
     * wish to execute code while they are active. For example,
     * <code>Runnable</code> is implemented by class <code>Thread</code>.
     * Being active simply means that a thread has been started and has not
     * yet been stopped.
     * <p>
     * In addition, <code>Runnable</code> provides the means for a class to be
     * active while not subclassing <code>Thread</code>. A class that implements
     * <code>Runnable</code> can run without subclassing <code>Thread</code>
     * by instantiating a <code>Thread</code> instance and passing itself in
     * as the target.  In most cases, the <code>Runnable</code> interface should
     * be used if you are only planning to override the <code>run()</code>
     * method and no other <code>Thread</code> methods.
     * This is important because classes should not be subclassed
     * unless the programmer intends on modifying or enhancing the fundamental
     * behavior of the class.
     *  * @author  Arthur van Hoff
     * @see     java.lang.Thread
     * @see     java.util.concurrent.Callable
     * @since   JDK1.0
     */
    • Runnable 接口可以被任何想要被一个线程运行的接口继承实现;继承 Runnable 接口的类必须有一个 run() 方法;
    • Runnable 接口被设计的目的是为那些当其处于活跃期时期望运行代码的对象提供一个公共的协议;处于活跃期简单的说就是一个线程已经启动但还没有结束
    • 继承 Runnable 接口实现线程,不需继承 Thread;而将类本身作为 Thread 中的目标 target
    • Runnable 接口最好不要继承,除非开发者想要更好的扩展此接口的功能

    类注解

    @FunctionalInterface
    public interface Runnable {
    }
    • @FunctionalInterface 用来标记函数式编程接口
      • 函数式编程接口:指仅仅只包含一个抽象方法的接口
      • 该注解不是必须的,如果一个接口符合”函数式接口”定义,那么加不加该注解都没有影响
      • 加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错

    run() 方法

        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    • 当一个对象实现 Runnnable 接口被用来创建一个线程,线程的启动导致该对象的 run 方法被另一个线程调用

    参考资料

    更多相关内容
  • autosar swc runnable

    2022-05-24 09:45:17
    Autosar SWC在Simulink中设置多个runnable的测试模型及生成的代码及Arxml文件
  • 主要介绍了java Runnable接口创建线程的相关资料,需要的朋友可以参考下
  • 实现Runnable接口的类必须使用Thread类的实例才能创建线程,通过Runnable接口创建线程分为以下两步
  • 这是一道面试题,创建多线程时,使用继承Thread类和实现Runnable接口有哪些区别呢? 一、Thread 先来看看Thread类和其中的start()方法 class Thread implements Runnable{.....} // 可见,Thread类实现了Runnable...
  • 在Java中只支持单继承,因此通过继承Thread类创建线程有一定的局限性,这时可以使用另一种方式,即实现Runnable接口来创建线程。通过这种方式需要在Thread(Runnable target)的构造方法中,传递一个实现了Runnable...
  • 本课讲的是如何实现一个Runnable,在一个独立线程上运行Runnable.run()方法.Runnable对象执行特别操作有时叫作任务。 Thread和Runnable都是基础的类,靠他们自己,能力有限。作为替代,Android有强大的基础类,像...
  • Thread和Runnable 的区别在面试当中是比较容易考的,自己又刚好在做这个的实验课题,于是乎,决定好好的学习这一部分知识,并把我查过的资料,通过自己的理解,给大家整理出来。  目录  面向小白学习法——Thread...
  • 1、Java有两种实现多线程的方式:通过Runnable接口、通过Thread直接实现,请掌握这两种实现方式,并编写示例程序。 2、多线程是并发执行的,交替占有cpu执行,请编写示例程序,并观察输出结果。 3、采用线程同步方法...
  • 本篇文章是对在Android中Handler Runnable与Thread的区别进行了详细的分析介绍,需要的朋友参考下
  • 本篇文章介绍了,java中使用Runnable接口创建线程的方法。需要的朋友参考下
  • 一个简单的多线程代码示例,Java实现,用于实现同一时刻,只允许一个线程调用执行的代码块或类,即synchronized的如何使用(多线程实现),实现 Runnable
  • java多线程Runnable实例

    2014-01-24 21:38:58
    java多线程runnable实例,经过测试的,可以直接运行
  • 实现 Runnable 接口 说明 java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了。 java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来...

    1. 实现 Runnable 接口

    • 说明
    1. java是单继承的,在某些情况下一个类可能已经继承了某个父类,这时在用继承Thread类方法来创建线程显然不可能了。
    2. java设计者们提供了另外一个方式创建线程,就是通过实现Runnable接口来创建线程
    • 应用案例
      请编写程序,该程序可以每隔1秒。在控制台输出“你好,兮动人”,当输出10次后,自动退出。
      使用实现Runnable接口的方式实现。
    public class Thread02 {
        public static void main(String[] args) {
            Dog dog = new Dog();
            //dog.start(); //这里不能调用 start 方法
            //创建了 Thread 对象,把 dog 对象(实现了 Runnable ),放入了 Thread
            Thread thread = new Thread(dog);
            thread.start();
        }
    }
    
    
    
    class Dog implements Runnable { //通过实现Runnable接口来实现
    
        int count =  0;
    
        @Override
        public void run() { //普通方法
            while (true) {
                System.out.println("你好,兮动人-" + (++count) + Thread.currentThread().getName());
    
                //休眠1秒
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (count == 10) {
                    break;
                }
            }
        }
    }
    

    在这里插入图片描述

    • 这里底层使用了设计模式【代理模式】=> 代码模拟实现Runnable接口 开发线程的机制。
    public class Thread02 {
        public static void main(String[] args) {
    
            Tiger tiger = new Tiger();
            ThreadProxy threadProxy = new ThreadProxy(tiger);
            threadProxy.start();
        }
    }
    
    class Animal {}
    
    class Tiger extends Animal implements Runnable {
    
        @Override
        public void run() {
            System.out.println("老虎...");
        }
    }
    
    //线程代理类,模拟了一个极简的Thread类
    class ThreadProxy implements Runnable { //可以把 Proxy 类当做 Thread
    
        private Runnable target = null; // 属性类型 是 Runnable
    
        @Override
        public void run() {
            if (target != null) {
                target.run();//动态绑定(运行类型是Tiger)
            }
        }
    
        public ThreadProxy(Runnable target) {
            this.target = target;
        }
    
        public void start() {
            start0();//这个方法是真正实现多线程的方法
        }
    
        public void start0() {
            run();
        }
    }
    

    在这里插入图片描述

    2. 线程使用应用案例–多线程执行

    • 请编写一个程序,创建两个线程,一个线程每隔1秒输出“hello,world”,输出10次,退出,另一个线程每隔1秒输出“hi”,输出5次退出。
    public class Thread03 {
        public static void main(String[] args) {
            T1 t1 = new T1();
            T2 t2 = new T2();
            Thread thread1 = new Thread(t1);
            thread1.start();
            Thread thread2 = new Thread(t2);
            thread2.start();
        }
    }
    
    class T1 implements Runnable {
    
        int count = 0;
    
        @Override
        public void run() {
            while (true) {
                System.out.println("hello world" + (++count));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (count == 10) {
                    break;
                }
            }
        }
    }
    
    class T2 implements Runnable {
    
        int count = 0;
    
        @Override
        public void run() {
            while (true) {
                System.out.println("hi" + (++count));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (count == 5) {
                    break;
                }
            }
        }
    }
    

    在这里插入图片描述

    3. 如何理解线程

    在这里插入图片描述
    在这里插入图片描述

    展开全文
  • Java线程状态RUNNABLE详解

    千次阅读 2020-11-03 20:53:50
    什么是 RUNNABLE? 直接看它的 Javadoc 中的说明: 一个在 JVM 中执行 的线程处于这一状态中。(A thread executing in the Java virtual machine is in this state.) 而传统的进(线)程状态一般划分如下(基于...

    Java虚拟机层面所暴露给我们的状态,与操作系统底层的线程状态是两个不同层面的事。具体而言,这里说的 Java 线程状态均来自于 Thread 类下的 State 这一内部枚举类中所定义的状态:

    在这里插入图片描述

    什么是 RUNNABLE?

    直接看它的 Javadoc 中的说明:

    一个在 JVM 中执行 的线程处于这一状态中。(A thread executing in the Java virtual machine is in this state.)

    而传统的进(线)程状态一般划分如下(基于操作系统层面,以cpu为中心):

    在这里插入图片描述

    注:这里的进程指早期的单线程 进程,这里所谓进程状态实质就是线程状态。

    那么 runnable 与图中的 ready 与 running 区别在哪呢?

    与传统的ready状态的区别

    更具体点,javadoc 中是这样说的:

    处于 runnable 状态下的线程正在 Java 虚拟机中执行,但它可能正在等待 来自于操作系统的其它资源,比如处理器。A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

    显然,runnable 状态实质上是包括了 ready 状态的。甚至还可能有包括上图中的 waiting 状态的部分细分状态,在后面我们将会看到这一点。

    与传统的running状态的区别

    有人常觉得 Java 线程状态中还少了个 running 状态,这其实是把两个不同层面的状态混淆了。对 Java 线程状态而言,不存在所谓的running 状态,它的 runnable 状态包含了 running 状态。

    我们可能会问,为何 JVM 中没有去区分这两种状态呢?

    现在的时分 (time-sharing)多任务 (multi-task)操作系统架构通常都是用所谓的“时间分片 (time quantum or time slice)”方式进行抢占式 (preemptive)轮转调度(round-robin式)。更复杂的可能还会加入优先级(priority)的机制。

    这个时间分片通常是很小的,一个线程一次最多只能在 cpu 上运行比如10-20ms 的时间(此时处于 running 状态),也即大概只有0.01秒这一量级,时间片用后就要被切换下来放入调度队列的末尾等待再次调度。(也即回到 ready 状态)

    注:如果期间进行了 I/O 的操作还会导致提前释放时间分片,并进入等待队列。 又或者是时间分片没有用完就被抢占,这时也是回到 ready 状态。

    这一切换的过程称为线程的上下文切换 (context switch),当然 cpu 不是简单地把线程踢开就完了,还需要把被相应的执行状态保存到内存中以便后续的恢复执行。

    显然,10-20ms 对人而言是很快的, 不计切换开销(每次在1ms 以内),相当于1秒内有50-100次切换。事实上时间片经常没用完,线程就因为各种原因被中断,实际发生的切换次数还会更多。

    也这正是单核 CPU 上实现所谓的“ 并发(concurrent)”的基本原理,但其实是快速切换所带来的假象,这有点类似一个手脚非常快的杂耍演员可以让好多个球同时在空中运转那般。

    时间分片也是可配置的,如果不追求在多个线程间很快的响应,也可以把这个时间配置得大一点,以减少切换带来的开销。

    如果是多核CPU,才有可能实现真正意义上的并发,这种情况通常也叫并行 ,不过你可能也会看到这两词会被混着用,这里就不去纠结它们的区别了。

    通常,Java的线程状态是服务于监控的,如果线程切换得是如此之快,那么区分 ready 与 running 就没什么太大意义了。

    当你看到监控上显示是 running 时,对应的线程可能早就被切换下去了,甚至又再次地切换了上来,也许你只能看到 ready 与 running 两个状态在快速地闪烁。

    当然,对于精确的性能评估而言,获得准确的 running 时间是有必要的。

    现今主流的 JVM 实现都把 Java 线程一一映射到操作系统底层的线程上,把调度委托给了操作系统,我们在虚拟机层面看到的状态实质是对底层状态的映射及包装(非一一对应关系)。JVM 本身没有做什么实质的调度,把底层的 ready 及 running 状态映射上来也没多大意义,因此,统一成为runnable 状态是不错的选择。

    我们将看到,Java 线程状态的改变通常只与自身显式引入的机制有关。

    当I/O阻塞时

    我们知道传统的I/O都是阻塞式(blocked)的,原因是I/O操作比起cpu来实在是太慢了,可能差到好几个数量级都说不定。如果让 cpu 去等I/O 的操作,很可能时间片都用完了,I/O 操作还没完成呢,不管怎样,它会导致 cpu 的利用率极低。

    所以,解决办法就是:一旦线程中执行到 I/O 有关的代码,相应线程立马被切走,然后调度 ready 队列中另一个线程来运行。这时执行了 I/O 的线程就不再运行,即所谓的被阻塞了。它也不会被放到调度队列中去,因为很可能再次调度到它时,I/O 可能仍没有完成。

    线程会被放到所谓的等待队列中,处于上图中的 waiting 状态:

    在这里插入图片描述
    当然了,我们所谓阻塞只是指这段时间 cpu 暂时不会理它了,但另一个部件比如硬盘则在努力地为它服务。cpu 与硬盘间是并行的。如果把线程视作为一个 job,这一 job 由 cpu 与硬盘交替协作完成,当在 cpu 上是 waiting 时,在硬盘上却处于 running,只是我们在操作系统层面讨论线程状态时通常是围绕着 cpu 这一中心去述说的。

    而当 I/O 完成时,则用一种叫中断 (interrupt)的机制来通知 cpu:也即所谓的“中断驱动 (interrupt-driven)”,现代操作系统基本都采用这一机制。

    某种意义上,这也是控制反转 (IoC)机制的一种体现,cpu不用反复去询问硬盘,这也是所谓的“好莱坞原则”—Don’t call us, we will call you.好莱坞的经纪人经常对演员们说:“别打电话给我,(有戏时)我们会打电话给你。”

    在这里,硬盘与 cpu 的互动机制也是类似,硬盘对 cpu 说:”别老来问我 IO 做完了没有,完了我自然会通知你的“

    当然了,cpu 还是要不断地检查中断,就好比演员们也要时刻注意接听电话,不过这总好过不断主动去询问,毕竟绝大多数的询问都将是徒劳的。

    cpu 会收到一个比如说来自硬盘的中断信号,并进入中断处理例程,手头正在执行的线程因此被打断,回到 ready 队列。而先前因 I/O 而waiting 的线程随着 I/O 的完成也再次回到 ready 队列,这时 cpu 可能会选择它来执行。

    另一方面,所谓的时间分片轮转本质上也是由一个定时器定时中断来驱动的,可以使线程从 running 回到 ready 状态:

    在这里插入图片描述
    比如设置一个10ms 的倒计时,时间一到就发一个中断,好像大限已到一样,然后重置倒计时,如此循环。与 cpu 正打得火热的线程可能不情愿听到这一中断信号,因为它意味着这一次与 cpu 缠绵的时间又要到头了…奴为出来难,何日君再来?

    现在我们再看一下 Java 中定义的线程状态,嘿,它也有 BLOCKED(阻塞),也有 WAITING(等待),甚至它还更细,还有TIMED_WAITING。

    现在问题来了,进行阻塞式 I/O 操作时(相对于底层系统cpu来说,线程为阻塞状态),Java 的线程状态(jvm层面上)究竟是什么?是 BLOCKED?还是 WAITING?

    可能你已经猜到,既然放到 RUNNABLE 这一主题下讨论,其实状态还是 RUNNABLE。我们也可以通过一些测试来验证这一点:

    @Test
    public void testInBlockedIOState() throws InterruptedException {
        Scanner in = new Scanner(System.in);
        // 创建一个名为“输入输出”的线程t
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 命令行中的阻塞读
                    String input = in.nextLine();
                    System.out.println(input);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                  IOUtils.closeQuietly(in);
                }
            }
        }, "输入输出"); // 线程的名字
    
        // 启动
        t.start();
    
        // 确保run已经得到执行
        Thread.sleep(100);
    
        // 状态为RUNNABLE
        assertThat(t.getState()).isEqualTo(Thread.State.RUNNABLE);
    }
    

    在最后的语句上加一断点,监控上也反映了这一点:

    在这里插入图片描述
    网络阻塞时同理,比如socket.accept,我们说这是一个“阻塞式(blocked)”式方法,但线程状态还是 RUNNABLE。

    @Test
    public void testBlockedSocketState() throws Exception {
        Thread serverThread = new Thread(new Runnable() {
            @Override
            public void run() {
                ServerSocket serverSocket = null;
                try {
                    serverSocket = new ServerSocket(10086);
                    while (true) {
                        // 阻塞的accept方法
                        Socket socket = serverSocket.accept();
                        // TODO
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }, "socket线程"); // 线程的名字
        serverThread.start();
    
        // 确保run已经得到执行
        Thread.sleep(500);
    
        // 状态为RUNNABLE
        assertThat(serverThread.getState()).isEqualTo(Thread.State.RUNNABLE);
    
    }
    

    监控显示:

    在这里插入图片描述
    当然,Java 很早就引入了所谓 nio(新的IO)包,至于用 nio 时线程状态究竟是怎样的,这里就不再一一具体去分析了。至少我们看到了,进行传统上的 IO 操作时,口语上我们也会说“阻塞”,但这个“阻塞”与线程的 BLOCKED 状态是两码事!

    如何看待RUNNABLE状态?

    首先还是前面说的,注意分清两个层面:虚拟机层面(vm)和操作系统层面(os)

    虚拟机是骑在你操作系统上面的,身下的操作系统是作为某种资源为满足虚拟机的需求而存在的。当进行阻塞式的 IO 操作时,或许底层的操作系统线程确实处在阻塞状态,但我们关心的是 JVM 的线程状态。

    JVM 并不关心底层的实现细节,什么时间分片也好,什么 IO 时就要切换也好,它并不关心。

    前面说到,“处于 runnable 状态下的线程正在* Java 虚拟机中执行,但它 可能正在等待*来自于操作系统的其它资源,比如处理器。”

    JVM 把那些都视作资源,cpu 也好,硬盘,网卡也罢,有东西在为线程服务,它就认为线程在“执行”。处于 IO 阻塞,只是说 cpu 不执行线程了,但网卡可能还在监听呀,虽然可能暂时没有收到数据。

    所以 JVM 认为线程还在执行。而操作系统的线程状态是围绕着 cpu 这一核心去述说的,这与 JVM 的侧重点是有所不同的。

    前面我们也强调了“Java 线程状态的改变通常只与自身显式引入的机制有关”,如果 JVM 中的线程状态发生改变了,通常是自身机制引发的。比如 synchronize 机制有可能让线程进入BLOCKED 状态,sleep,wait等方法则可能让其进入 WATING 之类的状态。

    展开全文
  • 使用Runnable接口创建线程,很简单

    千次阅读 2022-02-19 12:39:18
    使用Runnable接口创建线程 首先Java创建线程可以通过三种方法: 即: 1.继承Thread类创建线程类(重点) 2.通过Runnable接口创建线程类(重点) 3.通过Callable接口(了解即可) 今天,使用Runnable接口创建线程。...

    大家好,今天分享.使用Runnable接口创建线程

    首先Java创建线程可以通过三种方法:
    即:

    1.继承Thread类创建线程类(重点)

    2.通过Runnable接口创建线程类(重点)

    3.通过Callable接口(了解即可)

    今天,使用Runnable接口创建线程。

    步骤:

    1.定义MyRunnable类实现.Runnable接口
    2.创建run()方法,编写线程执行体
    3.创建线程对象,调用start()方法启动线程

    package Demo01;
    
    public class Thread03  implements Runnable{
    //    创建线程的第二种方式:
    //
    //    1.实现Runnable接口
        //2.重写run()方法,编写线程执行体
         //3.创建线程对象,调用start()方法启动线程
         public void run()  {
             //run方法线程体
             for (int i = 0; i < 400; i++) {
                 System.out.println("我在吃饭"+i);     //输出的信息
    
    
             }
         }
    
        public static void main(String[] args) {     //这里是主线程
             
             
    
    
            Thread03 thread03 =new Thread03();    //创建Runnable接口的实现类对象
            
    
    
            Thread thread =new Thread(thread03);      //创建线程对象,通过线程对象来启动线程
            
            
            thread.start();     //开启线程
    
    
            for (int i = 0; i < 300; i++) {
                System.out.println("多线程"+i);
            }
    
        }
    }
    

    它的执行结果:

    在这里插入图片描述
    解释:
    1.它的执行结果和 Thread继承的效果是一样的

    2.调用start()方法启动线程: 结果就是线程以交替同时启动

    这里还有注意点:

    这两行代码(注意)

      //    Thread thread =new Thread(thread03);      //创建线程对象,通过线程对象来启动线程
    
    
          //  thread.start();     //开启线程
    

    它等效于下面这一行代码:

       new Thread(thread03).start();
    

    整体代码在下面:

    package Demo01;
    
    public class Thread03  implements Runnable{
    //    创建线程的第二种方式:
    //
    //    1.实现Runnable接口
        //2.重写run()方法,编写线程执行体
         //创建线程对象,调用start()方法启动线程
         public void run()  {
             //run方法线程体
             for (int i = 0; i < 400; i++) {
                 System.out.println("我在吃饭"+i);     //输出的信息
    
    
             }
         }
    
        public static void main(String[] args) {     //这里是主线程
    
    
    
    
            Thread03 thread03 =new Thread03();    //创建Runnable接口的实现类对象
    
    
    
        //    Thread thread =new Thread(thread03);      //创建线程对象,通过线程对象来启动线程
    
    
          //  thread.start();     //开启线程
             new Thread(thread03).start();     //它等效上面两行被注释掉的代码
             
    
            for (int i = 0; i < 300; i++) {
                System.out.println("多线程"+i);
            }
    
        }
    }
    

    这是它的执行结果:(它是一样的效果)

    在这里插入图片描述
    它是一样的效果

    下面我们使用Runnable接口的方式来实现之前的Thread实现下载图片:

    看源码:

    package Demo02;
    
    import org.apache.commons.io.FileUtils;
    
    import javax.imageio.IIOException;
    import java.io.File;
    import java.io.IOException;
    import java.net.URL;
    
    public class ThreadTest  implements Runnable {     //这一行要注意
        private String url;
        private String name;
    
        public ThreadTest(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) {
            ThreadTest k1 = new ThreadTest("https://img-home.csdnimg.cn/images/20220218094038.jpg ", "1.jpg");
            ThreadTest k2 = new ThreadTest("https://img-home.csdnimg.cn/images/20220218094038.jpg ", "2.jpg");
            ThreadTest k3 = new ThreadTest("https://img-home.csdnimg.cn/images/20220218094038.jpg ", "3.jpg");
    
          new Thread(k1).start();     //这是我们改动的地方
          new Thread(k2).start();
          new Thread(k3).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方法异常");
            }
        }
    }
    

    看结果:

    在这里插入图片描述

    就是这样的

    总结:

    继承Thread 类
    子类继承Thread类具有多线程能力
    启动线程: 子类对象.start()
    不建议使用:
    OOP单继承有局限性

    实现接口Runnable具有多线程能力

    启动线程:传入目标对象+Thread对象.start ()

    推荐使用:避免单继承局限性,灵活方便,方便同一对象被多个线程使用

    好了,有关于使用Runnable接口创建线程就到这里了,谢谢大家

    展开全文
  • qt-runnable

    2021-05-06 18:45:16
    Runnable.7z,Runnable,SignalRunnable.cpp,mainwindow.cpp,mainwindow.h,Runnable.pro.user,Runnable.pro,main.cpp,SignalRunnable.h
  • 彻底理解Runnable和Thread的区别

    万次阅读 多人点赞 2019-07-30 09:45:42
      在实际工作中,我们很可能习惯性地选择Runnable或Thread之一直接使用,根本没在意二者的区别,但在面试中很多自以为是的菜货面试官会经常而且非常严肃的问出:请你解释下Runnable或Thread的区别?尤其是新手就...
  • 在Java中创建线程有两种方法:使用Thread类和使用Runnable接口。在使用Runnable接口时需要建立一个Thread实例。因此,无论是通过Thread类还是Runnable接口建立线程,都必须建立Thread类或它的子类的实例。
  • 您所要做的就是创建一个与命令完全相同的类,并使其继承自 Runnable 类。 class LS include Runnable end 这为您提供了控制ls命令执行的基础知识。 您可以使用executes宏覆盖命令的名称: class MyLs include ...
  • Runnable

    2021-01-04 14:59:51
    创建一个Runnable接口的实现类 package ThreadDemo01;/* @Author wanghongyuan @Date 2021/1/4 */ // 1.创建一个Runnable接口的实现类 public class RunnableImpl implements Runnable{ // 2.在实现类中重写...
  • 我有一个带有主标签页活动的Android应用程序,并且在单个标签页内有多个活动。...但是,我需要这些Runnable仅在主选项卡活动的Runnable完成创建列表时才运行,否则我将得到一个空列表。我正在尝试找到一种...
  • java中Runnable和Callable的区别 在java的多线程开发中Runnable一直以来都是多线程的核心,而Callable是java1.5添加进来的一个增强版本。 本文我们会详细探讨Runnable和Callable的区别。 运行机制 首先看下Runnable...
  • 大家都知道Runnable和Callable接口都可以作为其他线程执行的任务,但是Runnable接口的run方法没有返回值,而Callable接口的call方法有返回值,那么Callable接口是如何做到的呢?在此我给出一个Demo,看看通过...
  • Java:从Runnable返回结果

    千次阅读 2021-07-16 23:00:57
    Suppose the following simplified example. Let B represent a class processing some raster data:import java.awt.image....public class B implements Runnable{private boolean c;private Runnable ...
  • Runnable的使用

    万次阅读 2020-10-04 12:33:30
    Runnable 定义MyRunnable类实现Runnable接口。 实现run()方法,编写线程执行体。 创建线程对象,调用start()方法启动线程。 提示:推荐使用Runnable对象,因为Java单继承的局限性 参考代码 //创建线程方式二...
  • 1、实现Runnable接口方式实现多线程 与继承Thread类相比,实现Runnable接口的MyThread类在结构上与之前是没有区别的,但是有一点是有严重区别的,如果继承了Thread类,那么可以直接继承start()方法,但是实现...
  • 各位小伙伴们大家好,这次小编要介绍的是Runnable表达式当我们要启动一个线程去完成任务的时候,通常的做法会通过java.lang.Runnable接口来定义任务内容,并使用java.lang.Thread类来启动线程,代码如下:/*创建...
  • Thread和Runnable的区别

    2022-06-12 09:59:29
    Thread和Runnable的区别
  • Thread和Runnable区别

    2022-06-05 00:32:08
    (实现Runnable接口),代码如下: Thread和Runnable代码的区别:

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 642,774
精华内容 257,109
关键字:

runnable