java高并发代码示例 java实现高并发( 三 )


接下来 , 在try代码块中,首先判断是否可以中断当前任务所在的线程来取消任务的运行 。如果可以中断当前任务所在的线程 , 则以一个Thread临时变量来指向运行任务的线程,当指向的变量不为空时 , 调用线程对象的interrupt()方法来中断线程的运行,最后将线程标记为被中断的状态 。如下所示 。
这里,发现变更任务状态使用的是UNSAFE.putOrderedInt()方法,这个方法是个什么鬼呢?点进去看一下,如下所示 。
可以看到,又是一个本地方法 , 嘿嘿,这里先不管它,后续文章会详解这些方法的作用 。
接下来,cancel(boolean)方法会进入finally代码块,如下所示 。
可以看到在finallly代码块中调用了finishCompletion()方法,顾名思义 , finishCompletion()方法表示结束任务的运行,接下来看看它是如何实现的 。点到finishCompletion()方法中看一下,如下所示 。
在finishCompletion()方法中,首先定义一个for循环,循环终止因子为waiters为null,在循环中,判断CAS操作是否成功,如果成功进行if条件中的逻辑 。首先,定义一个for自旋循环,在自旋循环体中,唤醒WaitNode堆栈中的线程,使其运行完成 。当WaitNode堆栈中的线程运行完成后,通过break退出外层for循环 。接下来调用done()方法 。done()方法又是个什么鬼呢?点进去看一下,如下所示 。
可以看到,done()方法是一个空的方法体 , 交由子类来实现具体的业务逻辑 。
当我们的具体业务中,需要在取消任务时,执行一些额外的业务逻辑,可以在子类中覆写done()方法的实现 。
(5)get()方法
继续向下看FutureTask类的代码,FutureTask类中实现了两个get()方法,如下所示 。
没参数的get()方法为当任务未运行完成时,会阻塞,直到返回任务结果 。有参数的get()方法为当任务未运行完成,并且等待时间超出了超时时间,会TimeoutException异常 。
两个get()方法的主要逻辑差不多,一个没有超时设置,一个有超时设置 , 这里说一下主要逻辑 。判断任务的当前状态是否小于或者等于COMPLETING,也就是说,任务是NEW状态或者COMPLETING,调用awaitDone()方法,看下awaitDone()方法的实现,如下所示 。
接下来 , 拆解awaitDone()方法 。在awaitDone()方法中 , 最重要的就是for自旋循环 , 在循环中首先判断当前线程是否被中断 , 如果已经被中断 , 则调用removeWaiter()将当前线程从堆栈中移除,并且抛出InterruptedException异常,如下所示 。
接下来,判断任务的当前状态是否完成,如果完成 , 并且堆栈句柄不为空,则将堆栈中的当前线程设置为空,返回当前任务的状态,如下所示 。
当任务的状态为COMPLETING时,使当前线程让出CPU资源,如下所示 。
如果堆栈为空 , 则创建堆栈对象 , 如下所示 。
如果queued变量为false , 通过CAS操作为queued赋值,如果awaitDone()方法传递的timed参数为true,则计算超时时间,当时间已超时,则在堆栈中移除当前线程并返回任务状态 , 如下所示 。如果未超时,则重置超时时间,如下所示 。
如果不满足上述的所有条件 , 则将当前线程设置为等待状态 , 如下所示 。
接下来,回到get()方法中,当awaitDone()方法返回结果,或者任务的状态不满足条件时 , 都会调用report()方法,并将当前任务的状态传递到report()方法中,并返回结果,如下所示 。
看来 , 这里还要看下report()方法?。憬タ聪聄eport()方法的实现,如下所示 。

推荐阅读