源码
Runnable
函数式接口
package java.lang;
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
Thread
就是一个典型的静态代理模式
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
FutureTask的run()实际上调用的是Callable的call()方法,返回的realut可以通过get()方法获取
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);
}
类图
一、继承Thread
继承Thread,重写run方法
@Test
public void test2(){
// 创建线程对象
Thread t = new subThread();
// 启动线程
t.start();
}
class subThread extends Thread{
@Override
public void run() {
System.out.println("任务1");
}
}
或者
匿名子类
@Test
public void test1(){
// 创建线程对象
Thread t = new Thread() {
@Override
public void run() {
System.out.println("任务1.1");
}
};
// 启动线程
t.start();
}
二、给Thred对象传入Runnable对象(推荐)
@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");
}
}
推荐写法,使用lamada表达式生成Runable的匿名内部类对象,再传给Thred对象。
把任务和线程分开,更加灵活
@Test
public void test4(){
Runnable runnable = () -> System.out.println("任务2.2");
Thread thread = new Thread(runnable);
thread.start();
}
原理
Thread的run方法,使用到了静态代理模式,执行thred对象的run实际上执行的是匿名Runnable实现类对象的run方法。
@Override
public void run() {
if (target != null) {
target.run();
}
}
三、给Thread对象传入FutureTask对象
@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);
}