Java并发编程:Java创建线程的三种方式 (2)

同时,将成员变量state置为NEW,当启动task后,其run方法就会执行Callable的call()方法,

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 { //把call()的返回结果复制给result result = c.call(); ran = true; } catch (Throwable ex) { result = null; ran = false; setException(ex); } if (ran) //将结果设置给其他变量 set(result); } } finally { // runner must be non-null until state is settled to // prevent concurrent calls to run() runner = null; // state must be re-read after nulling runner to prevent // leaked interrupts int s = state; if (s >= INTERRUPTING) handlePossibleCancellationInterrupt(s); } } protected void set(V v) { if (UNSAFE.compareAndSwapInt(this, stateOffset, NEW, COMPLETING)) { //把传过来的值赋值给outcome成员 outcome = v; UNSAFE.putOrderedInt(this, stateOffset, NORMAL); // final state finishCompletion(); } }

run()方法中经过一系列的程序运行后,把call()的返回结果赋值给了outcome,然后当调用task.get()方法里获取的就是outcome的值了,这样一来,也就顺理成章的得到了返回结果。

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) //返回outcome的值 return (V)x; if (s >= CANCELLED) throw new CancellationException(); throw new ExecutionException((Throwable)x); }

可以看出,源码的运行逻辑还是比较清晰的,代码也比较容易理解,所以,我比较建议读者们有空可以多看看Java底层的源码,这样能帮助我们深入的理解功能是怎么实现的。

三种方式的对比

好了,创建线程的三种方式实例都说完了,接下来说下他们的对比。

从实现方式来说,使用Runnable接口和Callable接口的方式基本相同,区分的只是Callable实现的方法体可以有返回值,而继承Thread类是使用继承方式,所以,其实三种方法归为两类来分析即可。

1、使用继承Thread类的方式:

优势:编码简单,并且,当需要获取当前线程,可以直接用this

劣势:由于Java支持单继承,所以继承Thread后就不能继承其他父类

2、使用Runnable接口和Callable接口的方式:

优势:

比较灵活,线程只是实现接口,还可以继承其他父类。

这种方式下,多个线程可以共享一个target对象,非常适合多线程处理同一份资源的情形。

Callable接口的方式还能获取返回值。

劣势:

编码稍微复杂了点,需要创建更多对象。

如果想访问当前线程,需要用Thread.currentThread()方法。

总的来说,两种分类都有各自的优劣势,但其实后者的劣势相对优势来说不值一提,一般情况下,还是建议直接用接口的方式来创建线程,毕竟单一继承的劣势还是比较大的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfdsd.html