从我在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
这两个代码块有什么显著的区别吗?
我们可以重新访问我们希望我们的类表现为线程的基本原因吗?根本没有理由,我们只是想执行一个任务,最有可能是在异步模式下,这恰恰意味着任务的执行必须从我们的主线程和主线程分支,如果提前完成,可能会或可能不会等待分支路径(任务)。
如果这就是全部目的,那么我在哪里看到需要专门的线程。这可以通过从系统的线程池中提取一个RAW线程并分配给它我们的任务(可能是我们类的一个实例)来完成,就是这样。
因此,让我们遵循OOP概念,编写一个所需类型的类。做事有很多方法,用正确的方式做事很重要。
我们需要一个任务,所以写一个可以在线程上运行的任务定义。所以使用Runnable。
始终记住,机具专门用于传递行为,扩展用于传递特性/属性。
我们不希望线程的属性,而是希望我们的类作为一个可以运行的任务。
对于大多数工作线程来说,最好的方法是将线程完全封装在工作线程类中,这样就不会有任何外部干扰,导致不需要的和无效的线程/类状态。
我刚刚发布了一个示例,因此我也将与您分享:
/**
* 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();
}
}