线程与可运行

这个问题在这里已经有了答案:

  • “实现可运行”与“扩展线程”40个答案

  • 这是javadoc的状态

    两种方法可以创建一个新的执行线程。 一种是将一个类声明为Thread的子类 。 这个子类应该重写Thread类的run方法。 然后可以分配和启动子类的一个实例。 例如,计算大于所述值的素数的线程可以写成如下:

    另一种创建线程的方式是声明一个实现了Runnable接口的类。 那个类然后实现了run方法。 然后可以分配一个类的实例,在创建线程时作为参数传递并启动。 这种其他风格中的相同示例如下所示:

    所以这两种方式

    public class MyThread extends Thread {
        // overriden from Runnable, which Thread implements
        public void run() {
            ...
        }
    }
    
    ...
    MyThread thread = new MyThread();
    thread.start();
    

    要么

    public class MyRunnable implements Runnable{
        public void run() {
            ...
        }
    }
    ...
    Thread thread = new Thread(new MyRunnable());
    thread.start();
    

    您的counter字段是一个实例字段。

    在你的第一种情况下,这里创建的每个对象

     ExtendsThread tc1 = new ExtendsThread();
     tc1.start();
     Thread.sleep(1000); // Waiting for 1 second before starting next thread
     ExtendsThread tc2 = new ExtendsThread();
     tc2.start();
     Thread.sleep(1000); // Waiting for 1 second before starting next thread
     ExtendsThread tc3 = new ExtendsThread();
     tc3.start();
    

    将拥有自己的副本(这是实例变量的工作方式)。 所以当你启动每个线程时,每个线程都增加它自己的字段副本。

    在第二种情况下, 您正在使用Thread子类作为Thread构造函数的Runnable参数。

    ExtendsThread extendsThread = new ExtendsThread();
    Thread thread11 = new Thread(extendsThread);
    thread11.start();
    Thread.sleep(1000);
    Thread thread12 = new Thread(extendsThread);
    thread12.start();
    Thread.sleep(1000);
    Thread thread13 = new Thread(extendsThread);
    thread13.start();
    Thread.sleep(1000);
    

    它与您传递的ExtendsThread对象相同,所以其counter字段会被所有线程递增。 这几乎等同于您以前使用的ImplementsRunnable

    从评论中添加:

    首先要明白的是, Thread类实现了Runnable ,因此您可以在任何可以使用Runnable地方使用Thread实例。 例如,

    new Thread(new Thread()); // won't do anything, but just to demonstrate
    

    当你创建一个Thread

    new Thread(someRunnable);
    

    并启动它, 线程将调用给定的Runnable实例的run()方法 。 如果该Runnable实例碰巧也是Thread一个实例,那就这样吧。 这并没有改变任何东西。

    当你创建一个自定义线程时

    new ExtendsThread();
    

    并启动它,它自己调用run()


    实现Runnable的主要区别在于你不会'消耗'你的单一继承。 考虑这些类声明:

    public class HelloRunnable implements Runnable extends AbstractHello
    
    public class HelloRunnable extends Thread
    

    在继承方面,您可以使用Runnable做更多的事情。


    @BalwantChauhan:Runnable接口的一个常见用法是,因为我们知道在Java的情况下多重继承是不可能的。 现在假设你有一个场景需要扩展一个类,并且你想实现线程。 所以对于这些情况,如果我们继续进行线程,那么它是不可能实现的。 例如:假设(在Java Swing的情况下),如果你想创建一个框架,并且在你想要实现线程的框架类中,那么就不可能扩展JFrame和Thread类,所以在这种情况下,我们扩展了JFrame和实现Runnable。

    public class HelloFrame extends JFrame implements Runnable{
    
      ...
    
      public void run(){
        //  thread code
      }
    
      ...
    }  
    
    链接地址: http://www.djcxy.com/p/92065.html

    上一篇: Thread Vs Runnable

    下一篇: Implementing Runnable vs. extending Thread