【并发编程】创建线程的三种方法

源码

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);  
}

类图

【并发编程】创建线程的三种方法_第1张图片

一、继承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);  
  
}

你可能感兴趣的:(并发编程,java,开发语言)