从我在Java中使用线程的时间来看,我发现了两种编写线程的方法:

使用可运行的机具:

public class MyRunnable implements Runnable {
    public void run() {
        //Code
    }
}
//Started with a "new Thread(new MyRunnable()).start()" call

或者,使用扩展线程:

public class MyThread extends Thread {
    public MyThread() {
        super("MyThread");
    }
    public void run() {
        //Code
    }
}
//Started with a "new MyThread().start()" call

这两个代码块有什么显著的区别吗?


当前回答

故事的寓意:

仅当您想要覆盖某些行为时才继承。

或者更确切地说,它应该被理解为:

继承更少,接口更多。

其他回答

线程和可运行线程之间的差异。若我们使用线程类创建线程,则线程数等于我们创建的对象数。如果我们通过实现可运行接口来创建线程,那么我们可以使用单个对象来创建多个线程。因此,单个对象由多个线程共享。因此,它将占用更少的内存

因此,如果我们的数据不敏感,则取决于要求。所以它可以在多个线程之间共享,我们可以使用Runnable接口。

线程类定义了几个可由扩展类重写的方法。但要创建线程,我们必须重写run()方法。这同样适用于Runnable。

然而,Runnable是创建线程的首选方法。主要原因如下:

由于Runnable是一个接口,因此可以扩展其他类。但如果您扩展“线程”,则该选项将消失。如果您没有修改或增强大量Thread功能,那么扩展Thread类不是首选方法。

对于大多数工作线程来说,最好的方法是将线程完全封装在工作线程类中,这样就不会有任何外部干扰,导致不需要的和无效的线程/类状态。

我刚刚发布了一个示例,因此我也将与您分享:

/**
 * This worker can only run once
 * @author JayC667
 */
public class ProperThreading {

    private final Thread        mThread         = new Thread(() -> runWorkingLoop());   // if you want worker to be able to run multiple times, move initialisation into startThread()
    private volatile boolean    mThreadStarted  = false;
    private volatile boolean    mStopRequested  = false;

    private final long          mLoopSleepTime;

    public ProperThreading(final long pLoopSleepTime /* pass more arguments here, store in members */ ) {
        mLoopSleepTime = pLoopSleepTime;
    }

    public synchronized void startThread() {
        if (mThreadStarted) throw new IllegalStateException("Worker Thread may only be started once and is already running!");
        mThreadStarted = true;
        mThread.start();
    }

    private void runWorkingLoop() {
        while (!mStopRequested /* && other checks */ ) {
            try {
                // do the magic work here
                Thread.sleep(mLoopSleepTime);

            } catch (final InterruptedException e) {
                break;
            } catch (final Exception e) {
                // do at least some basic handling here, you should NEVER ignore exception unless you know exactly what you're doing, and then it should be commented!
            }
        }
    }

    public synchronized void stopThread() {
        if (!mThreadStarted) throw new IllegalStateException("Worker Thread is not even running yet!");
        mStopRequested = true;
        mThread.interrupt();
    }

}

简单的说法是:如果你实现了接口,这意味着你正在实现它的所有方法,如果你扩展了类,你正在继承你选择的方法。。。在这种情况下,只有一个名为Run()的方法,因此更好地实现Runnable接口。。

故事的寓意:

仅当您想要覆盖某些行为时才继承。

或者更确切地说,它应该被理解为:

继承更少,接口更多。