source code
Runnable
functional interface
package java.lang;
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Thread
It is a typical static proxy mode
public class Thread implements Runnable {
private Runnable target;
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
@Override
public void run() {
if (target != null) {
target.run();
}
}
}
FutureTask
The run() of FutureTask actually calls the call() method of Callable, and the returned realut can be obtained through the get() method
public void run() {
if (state != NEW ||
!UNSAFE.compareAndSwapObject(this, runnerOffset,
null, Thread.currentThread()))
return;
try {
Callable<V> c = callable;
if (c != null && state == NEW) {
V result;
boolean ran;
try {
result = c.call();
ran = true;
} catch (Throwable ex) {
result = null;
ran = false;
setException(ex);
}
if (ran)
set(result);
}
} finally {
if (s >= INTERRUPTING)
handlePossibleCancellationInterrupt(s);
}
}
protected void set(V v) {
if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) {
outcome = v;
UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state
finishCompletion();
}
}
public V get() throws InterruptedException, ExecutionException {
int s = state;
if (s <= COMPLETING)
s = awaitDone(false, 0L);
return report(s);
}
private V report(int s) throws ExecutionException {
Object x = outcome;
if (s == NORMAL)
return (V)x;
if (s >= CANCELLED)
throw new CancellationException();
throw new ExecutionException((Throwable)x);
}
Class Diagram
1. Inherit Thread
Inherit Thread, rewrite the run method
@Test
public void test2(){
// 创建线程对象
Thread t = new subThread();
// 启动线程
t.start();
}
class subThread extends Thread{
@Override
public void run() {
System.out.println("任务1");
}
}
or
anonymous subclass
@Test
public void test1(){
// 创建线程对象
Thread t = new Thread() {
@Override
public void run() {
System.out.println("任务1.1");
}
};
// 启动线程
t.start();
}
2. Pass the Runnable object to the Thred object (recommended)
@Test
public void test3(){
Runnable runnable = new RunnableImpl();
Thread thread = new Thread(runnable);
thread.start();
}
class RunnableImpl implements Runnable{
@Override
public void run() {
System.out.println("任务2");
}
}
The recommended writing method is to use lamada expressions to generate Runable anonymous inner class objects, and then pass them to Thred objects.
Separate tasks and threads for more flexibility
@Test
public void test4(){
Runnable runnable = () -> System.out.println("任务2.2");
Thread thread = new Thread(runnable);
thread.start();
}
Principle
Thread's run method uses the static proxy mode, and the run that executes the thred object actually executes the run method of the anonymous Runnable implementation class object.
@Override
public void run() {
if (target != null) {
target.run();
}
}
3. Pass the FutureTask object to the Thread object
@Test
public void test5() throws ExecutionException, InterruptedException {
// 创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {
System.out.println("任务3");
return 100;
});
// 参数1 是任务对象; 参数2 是线程名字,推荐
new Thread(task3, "t3").start();
// 主线程阻塞,同步等待 task 执行完毕的结果
Integer result = task3.get();
System.out.println(result);
}