runnable_runnable接口 - CSDN
精华内容
参与话题
  • JAVA 实现Runnable接口

    千次阅读 2014-09-23 17:38:57
     创建线程的第二种方式:实现Runnable接口  步骤:  1,定义类实现Runnable接口  2,覆盖Runnable接口中的run方法  将线程要运行的代码存放在该run方法中  3,通过Thread 类建立线程对象  4,将...
    /*
         需求: 实现一个售票程序
        
         创建线程的第二种方式:实现Runnable接口

         步骤:
         1,定义类实现Runnable接口
         2,覆盖Runnable接口中的run方法
              将线程要运行的代码存放在该run方法中

         3,通过Thread 类建立线程对象
         4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数
              为什么要将Runnable接口中的子类对象传递给Thread的构造函数
              因为,自定义的run方法所属的对象是Runnable接口的子类对象
              所以要让线程去指定指定对象的run方法,就必须明确该run方法所属对象。

         5,调用Thread类的start方法 开启线程并调用Runnable接口子类的run方法



    实现方式和继承方式的区别:

    实现方式好处:避免了单继承的局限性
    在定义建议使用实现方式

    两种方式区别:
    继承Thread:线程代码存放在Thread子类run方法中。
    实现Runnable:线程代码存放在接口的子类的run方法中、
    */

    class Tick implements Runnable
    {
         private int tick = 50;

         public void run()
         {
              while(true)
              {
                   if(tick > 0)
                        System.out.println( Thread.currentThread().getName() + " sail --" + tick--);
              }
         }
    }

    class TickDemo
    {
         public static void main(String []args)
         {
              Tick t = new Tick();

              Thread t1 = new Thread(t);
              Thread t2 = new Thread(t);
              Thread t3 = new Thread(t);
              Thread t4 = new Thread(t);

              t1.start();
              t2.start();
              t3.start();
              t4.start();

         }
    }

    展开全文
  • 彻底理解Runnable和Thread的区别

    万次阅读 多人点赞 2019-11-27 13:23:19
      在实际工作中,我们很可能习惯性地选择Runnable或Thread之一直接使用,根本没在意二者的区别,但在面试中很多自以为是的菜货面试官会经常而且非常严肃的问出:请你解释下Runnable或Thread的区别?尤其是新手就...

    欢迎关注鄙人公众号,技术干货随时看!
    在这里插入图片描述

      在实际工作中,我们很可能习惯性地选择Runnable或Thread之一直接使用,根本没在意二者的区别,但在面试中很多自以为是的菜货面试官会经常而且非常严肃的问出:请你解释下Runnable或Thread的区别?尤其是新手就容易上当,不知如何回答,就胡乱编一通。鄙人今天告诉你们这二者本身就没有本质区别,就是接口和类的区别。问出这个问题的面试官本身就是个二流子!如果非要说区别,请看如下:

    1. Runnable的实现方式是实现其接口即可
    2. Thread的实现方式是继承其类
    3. Runnable接口支持多继承,但基本上用不到
    4. Thread实现了Runnable接口并进行了扩展,而Thread和Runnable的实质是实现的关系,不是同类东西,所以Runnable或Thread本身没有可比性。

      网络上流传的最大的一个错误结论:Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 这是一个二笔的结论!网络得出此结论的例子如下:

    //program--Thread
    public class Test {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
    
            new MyThread().start();
            new MyThread().start();
    
        }
    
    
         static class MyThread extends Thread{
            private int ticket = 5;
            public void run(){
                while(true){
                    System.out.println("Thread ticket = " + ticket--);
                    if(ticket < 0){
                        break;
                    }
                }
            }
        }
    }
    

    运行结果如下:

    Thread ticket = 5
    Thread ticket = 5
    Thread ticket = 4
    Thread ticket = 3
    Thread ticket = 2
    Thread ticket = 1
    Thread ticket = 0
    Thread ticket = 4
    Thread ticket = 3
    Thread ticket = 2
    Thread ticket = 1
    Thread ticket = 0
    
    Process finished with exit code 0
    
    

      很显然,总共5张票但卖了10张。这就像两个售票员再卖同一张票,原因稍后分析。现在看看使用runnable的结果:

    //program--Runnable
    public class Test2 {
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            MyThread2 mt=new MyThread2();
            new Thread(mt).start();
            new Thread(mt).start();
    
    
        }
        static class MyThread2 implements Runnable{
            private int ticket = 5;
            public void run(){
                while(true){
                    System.out.println("Runnable ticket = " + ticket--);
                    if(ticket < 0){
                        break;
                    }
                }
            }
        }
    }
    

      运行结果如下:

    
    Runnable ticket = 5
    Runnable ticket = 4
    Runnable ticket = 3
    Runnable ticket = 1
    Runnable ticket = 0
    Runnable ticket = 2
    
    Process finished with exit code 0
    
    

      嗯,嗯,大多数人都会认为结果正确了,而且会非常郑重的得出:Runnable更容易可以实现多个线程间的资源共享,而Thread不可以! 真的是这样吗?大错特错!
      program–Thread这个例子结果多卖一倍票的原因根本不是因为Runnable和Thread的区别,看其中的如下两行代码:

            new MyThread().start();
            new MyThread().start();
    

      例子中,创建了两个MyThread对象,每个对象都有自己的ticket成员变量,当然会多卖1倍。如果把ticket定义为static类型,就离正确结果有近了一步(因为是多线程同时访问一个变量会有同步问题,加上锁才是最终正确的代码)。
    现在看program–Runnable例子中,如下代码:

            MyThread2 mt=new MyThread2();
            new Thread(mt).start();
            new Thread(mt).start();        
    

      只创建了一个Runnable对象,肯定只卖一倍票(但也会有多线程同步问题,同样需要加锁),根本不是Runnable和Thread的区别造成的。再来看一个使用Thread方式的正确例子:

    public class Test3  extends Thread {
    
            private int ticket = 10;
    
            public void run(){
                for(int i =0;i<10;i++){
                    synchronized (this){
                        if(this.ticket>0){
                            try {
                                Thread.sleep(100);
                                System.out.println(Thread.currentThread().getName()+"卖票---->"+(this.ticket--));
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
    
            public static void main(String[] arg){
                Test3 t1 = new Test3();
                new Thread(t1,"线程1").start();
                new Thread(t1,"线程2").start();
            }
    
    }
    

    运行结果如下:

    线程1卖票---->10
    线程1卖票---->9
    线程1卖票---->8
    线程1卖票---->7
    线程1卖票---->6
    线程1卖票---->5
    线程1卖票---->4
    线程1卖票---->3
    线程1卖票---->2
    线程1卖票---->1
    
    Process finished with exit code 0
    
    

      上例中只创建了一个Thread对象(子类Test3),效果和Runnable一样。synchronized这个关键字是必须的,否则会出现同步问题,篇幅太长本文不做讨论。
      上面讨论下来,Thread和Runnable没有根本的没区别,只是写法不同罢了,事实是Thread和Runnable没有本质的区别,这才是正确的结论,和自以为是的大神所说的Runnable更容易实现资源共享,没有半点关系!
      现在看下Thread源码:

    public
    class Thread implements Runnable {
        /* Make sure registerNatives is the first thing <clinit> does. */
        private static native void registerNatives();
        static {
            registerNatives();
        }
    
        private volatile String name;
        private int            priority;
        private Thread         threadQ;
        private long           eetop;
    

      可以看出,Thread实现了Runnable接口,提供了更多的可用方法和成员而已。

      结论,Thread和Runnable的实质是继承关系,没有可比性。无论使用Runnable还是Thread,都会new Thread,然后执行run方法。用法上,如果有复杂的线程操作需求,那就选择继承Thread,如果只是简单的执行一个任务,那就实现runnable。
      再遇到二笔面试官问Thread和Runnable的区别,你可以直接鄙视了!

    展开全文
  • Runnable

    千次阅读 2018-01-19 07:24:14
    Runnable 概述 java version “1.8.0_131” 多线程创建方式之一 public class RunnableTest implements Runnable{ // 实现 run() public void run() { System.out.println("thread"); } publ

    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 方法被另一个线程调用

    参考资料

    展开全文
  • 线程的创建——Thread,Runnable,Callable Thread类 Runnable接口 Callable接口(了解) Thread类 //创建线程方式一:继承Thread类,重写run方法 ,调用start开启线程 //总结:注意 线程开启不一定能立即执行,由CPU...

    基本概念

    • 程序:指令和数据的集合。 静态。
    • Process 进程 :执行程序的一次执行过程。 动态。 系统资源分配的单位
    • Thread 线程 : 一个进程中至少包含一个线程。 CPU调度和执行的单位。
      在这里插入图片描述

    线程的创建——Thread,Runnable,Callable

    Thread类
    Runnable接口
    Callable接口(了解)

    Thread类

    //创建线程方式一:继承Thread类,重写run方法 ,调用start开启线程
    //总结:注意 线程开启不一定能立即执行,由CPU调度执行
    public class TestThread1 extends Thread{
        @Override
        public void run() {
            //run方法线程体
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在学代码--");
            }
        }
    
        public static void main(String[] args) {
            //main线程,主线程
    
            //创建一个线程对象
            TestThread1 testThread1=new TestThread1();
            //调用start()方法开启线程
            testThread1.start();
            /*调用run方法
            testThread1.run();*/
    
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在学多线程--");
            }
    
        }
    }
    

    用start:我在学代码-- 和 我在学多线程-- 并行交替执行 交替输出
    用run(不是多线程了):先 我在学代码-- 后 我在学多线程–
    在这里插入图片描述

    Runnable接口

    //创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
    public class TestThread3 implements Runnable{
    
        @Override
        public void run() {
            //run方法线程体
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在学代码--");
            }
        }
    
        public static void main(String[] args) {
            //创建runnable接口的实现类对象
            TestThread3 testThread3=new TestThread3();
            //创建线程对象,通过线程对象来开启我们的线程 代理
           // Thread thread=new Thread(testThread3);
           // thread.start();
    new Thread(testThread3).start();
    
            for (int i = 0; i < 2000; i++) {
                System.out.println("我在学多线程--");
            }
        }
    }
    
    

    在这里插入图片描述

    发现并发问题

    //多个线程操作同一个对象
    //买火车票的例子
    
    //发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱。
    public class TestThread4 implements Runnable{
        //票数
        private int ticketNums=10;
        @Override
        public void run() {
            while (true){
                if (ticketNums<=0){
                    break;
                }
                //模拟延时
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"-->拿到了第"+ticketNums--+"票");
            }
        }
    
        public static void main(String[] args) {
            TestThread4 ticket=new TestThread4();
    
            new Thread(ticket,"xiaoming").start();
            new Thread(ticket,"xiaoli").start();
            new Thread(ticket,"xiaosun").start();
    
        }
    }
    

    在这里插入图片描述

    例题:龟兔赛跑

    //模拟龟兔赛跑
    public class Race implements Runnable{
    //胜利者
        private static String winner;
        @Override
        public void run() {
            for (int i = 0; i <= 100; i++) {
                //模拟兔子休息
                if (Thread.currentThread().getName().equals("兔子")&&i%10==0){
                    try {
                        Thread.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //判断比赛是否结束
                boolean flag=gameOver(i);
                //如果比赛结束了,就停止程序
                if (flag){
                    break;
                }
                System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");
            }
        }
    //判断是否完成比赛
        private boolean gameOver(int steps){
            if(winner!=null){
                return  true;
            }
            if(steps>=100){
                winner=Thread.currentThread().getName();
                System.out.println("winner is"+winner);
                return true;
            }
            return false;
        }
    
        public static void main(String[] args) {
    Race race=new Race();
    new Thread(race,"乌龟").start();
    new Thread(race,"兔子").start();
        }
    }
    

    在这里插入图片描述

    Callable接口

    了解就可

    静态代理模式

    //代理模式总结
    //真实对象和代理对象都要实现同一个接口
    //代理对象要代理真实角色
    
    //好处   代理对象可以做很多真实对象做不了的事  真实对象可以专注自己的事
    public class StaticProxy {
        public static void main(String[] args) {
            You you = new You();
          
            WeddingCompany weddingCompany=new WeddingCompany(you);   //替代了    you.HappyMarry();
            weddingCompany.HappyMarry();
        }
    }
    interface Marry{
        void HappyMarry();
    }
    //真实角色 你去结婚
    class You implements Marry{
    
        @Override
        public void HappyMarry() {
            System.out.println("qin is married.");
        }
    }
    //代理角色 帮助你去结婚
    class WeddingCompany implements Marry{
        //代理谁--》真实目标角色
    private Marry target;
    public WeddingCompany(Marry target){
        this.target=target;
    }
        @Override
        public void HappyMarry() {
            before();
            this.target.HappyMarry();   //这就是真实对象
            after();
        }
    
        private void after() {
            System.out.println("结婚后");
        }
    
        private void before() {
            System.out.println("结婚前");
        }
    }
    
    
    展开全文
  • 实现Runnable接口 继承Thread类 实现Callable接口 Runnable接口,其实就是提供一个run()方法,让实现它的类覆盖这个run()方法。 @FunctionalInterface public interface Runnable { /** * 当使用实现接口Runnable...
  • 创建线程的2种方式,一种是直接继承Thread,另外一种就是实现Runnable接口。  这2种方式都有一个缺陷就是:在执行完任务之后无法获取执行结果。  如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式...
  • 线程有三种:Thread,Runnable,Callable. Runnable和Callable的区别是, (1)Callable规定的方法是call(),Runnable规定的方法是run(). (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得 (3)call...
  • 你不知道的Runnable接口,深度解析Runnable接口

    万次阅读 多人点赞 2020-01-08 09:38:04
    本文描述的是Android中的Runnable接口。因Android中的线程源自于Java,所以首先需要了解Java中的线程,有关Java中的线程请看这篇文章Android(线程一) 线程 ! Java开发中,我们实现多线程,有两种方式,一种是继承...
  • 用lambda表达式实现Runnable

    万次阅读 2018-03-15 22:09:31
    new Thread(new Runnable() { @Override public void run() { System.out.println("Before Java8"); } }).start();new Thread( () -&gt; System.out.println("In Java8, Lambda expres...
  • 浅谈new Runnable()

    万次阅读 2018-09-06 15:49:35
    转自:...amp;fps=1 参考: https://www.cnblogs.com/lanzhi/p/6467266.html //匿名内部类中关于new Runnable()的使用 http://wiki.jikexueyuan.com/project/jav...
  • 1.第一种情况,有的测试类为空,只定义了一个类名,也就是类里面没有能运行的方法 2.第二种情况,测试类方法有错,或者没有添加注解。
  • Android Runnable 用法

    万次阅读 2010-06-30 15:09:00
    Runnable派生你的子类,重载run()方法。 然后调用View.post(myRunnableObj)即可把你的Runnable对象增加到UI线程中运行。   boolean android.view.View .post(Runnable action) ...
  • Thread 和 Runnable 的区别

    千次阅读 2016-08-03 23:42:57
    Thread 和 Runnable 的区别 实际上,Thread也是一个Runnable,它实现了Runnable接口,在Thread类中有一个Runnable类型的target字段,代表要被执行在这个子线程中的任务。 public class Thread implements...
  • Runnable获取线程名字

    千次阅读 2018-09-14 11:56:25
    Thread.currentThread().getName();
  • Spring异常:junit:no runnable methods 解决方法

    万次阅读 多人点赞 2018-08-04 18:02:34
     junit:no runnable methods 尝试解决方案: 1.导错了包:@Test时import的是@org.testng.annotations.Test 所以会报错  解决方法:改为import org.junit.Test;  2.忘记在方法前面加入@Test注解 ...
  • Java中的runnable方法的使用实例

    千次阅读 2018-05-03 11:23:47
  • 被自己蠢哭了的 Runnable.run()方法

    万次阅读 2018-11-16 11:12:04
    之前一直都是用new Thread().start()方法跑线程,昨天撸代码的时候,想起听哪位大佬和我提过,实现Runnable接口比继承Thread类要好。那就实现接口试下吧,结果出问题了,回想起来,真是被自己蠢哭了。。。 我的代码...
  • Thread.currentThread().getName()  
  • AutoSAR系列讲解(入门篇)2.4-Runnables可运行实体

    千次阅读 热门讨论 2019-07-22 15:24:28
    讲解一下Runnable和其工程的实际映射
  • 关于handler.post(Runnable runnable)

    千次阅读 2014-11-21 13:22:36
    关于这个handler.post(Runnable r)这个方法,用过很多次,
1 2 3 4 5 ... 20
收藏数 386,848
精华内容 154,739
关键字:

runnable