Future 定义了5个方法:
1)boolean cancel(boolean mayInterruptIfRunning):试图取消对此任务的执行 。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败 。当调用 cancel() 时,如果调用成功,而此任务尚未启动,则此任务将永不运行 。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程 。此方法返回后,对 isDone() 的后续调用将始终返回 true 。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true 。2)boolean isCancelled():如果在任务正常完成前将其取消,则返回 true 。3)boolean isDone():如果任务已完成,则返回 true 。可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true 。4)V get()throws InterruptedException,ExecutionException:如有必要,等待计算完成,然后获取其结果 。5)V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException: 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用) 。
看来 Future 接口也不能用在线程中,那怎么用,谁实现了 Future 接口呢?答:FutureTask 。
public class FutureTask<V> implements RunnableFuture<V> {...}public interface RunnableFuture<V> extends Runnable, Future<V> {void run();}FutureTask 实现了 Runnable 和 Future,所以兼顾两者优点,既可以在 Thread 中使用,又可以在 ExecutorService 中使用 。
看完上面啰哩啰嗦的介绍后,下面我们具体看一下具体使用的示例:
Callable<String> callable = new Callable<String>() {@Overridepublic String call() throws Exception {return "个人博客:sunfusheng.com";}};FutureTask<String> task = new FutureTask<String>(callable);Thread t = new Thread(task);t.start(); // 启动线程task.cancel(true); // 取消线程使用 FutureTask 的好处是 FutureTask 是为了弥补 Thread 的不足而设计的,它可以让程序员准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果 。FutureTask 是一种可以取消的异步的计算任务,它的计算是通过 Callable 实现的,它等价于可以携带结果的 Runnable,并且有三个状态:等待、运行和完成 。完成包括所有计算以任意的方式结束,包括正常结束、取消和异常 。
查看具体操作代码请参考 《个人学习项目DroidStudy》,感谢您的关注 。
● 多线程多线程的概念很好理解就是多条线程同时存在,但要用好多线程确不容易,涉及到多线程间通信,多线程共用一个资源等诸多问题 。
使用多线程的优缺点: 优点: 1)适当的提高程序的执行效率(多个线程同时执行) 。2)适当的提高了资源利用率(CPU、内存等) 。缺点: 1)占用一定的内存空间 。2)线程越多CPU的调度开销越大 。3)程序的复杂度会上升 。
对于多线程的示例代码感兴趣的可以自己写Demo啦,去运行体会,下面我主要列出一些多线程的技术点 。
synchronized同步块大家都比较熟悉,通过 synchronized 关键字来实现;所有加上 synchronized 的方法和块语句,在多线程访问的时候,同一时刻只能有一个线程能够访问 。
wait()、notify()、notifyAll()这三个方法是 java.lang.Object 的 final native 方法,任何继承 java.lang.Object 的类都有这三个方法 。它们是Java语言提供的实现线程间阻塞和控制进程内调度的底层机制,平时我们会很少用到的 。
wait(): 导致线程进入等待状态,直到它被其他线程通过notify()或者notifyAll唤醒,该方法只能在同步方法中调用 。
notify(): 随机选择一个在该对象上调用wait方法的线程,解除其阻塞状态,该方法只能在同步方法或同步块内部调用 。
notifyAll(): 解除所有那些在该对象上调用wait方法的线程的阻塞状态,同样该方法只能在同步方法或同步块内部调用 。
调用这三个方法中任意一个,当前线程必须是锁的持有者,如果不是会抛出一个 IllegalMonitorStateException 异常 。
wait() 与 Thread.sleep(long time) 的区别sleep():在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),该线程不丢失任何监视器的所属权,sleep() 是 Thread 类专属的静态方法,针对一个特定的线程 。wait() 方法使实体所处线程暂停执行,从而使对象进入等待状态,直到被 notify() 方法通知或者 wait() 的等待的时间到 。sleep() 方法使持有的线程暂停运行,从而使线程进入休眠状态,直到用 interrupt 方法来打断他的休眠或者 sleep 的休眠的时间到 。wait() 方法进入等待状态时会释放同步锁,而 sleep() 方法不会释放同步锁 。所以,当一个线程无限 sleep 时又没有任何人去 interrupt 它的时候,程序就产生大麻烦了,notify() 是用来通知线程,但在 notify() 之前线程是需要获得 lock 的 。另个意思就是必须写在 synchronized(lockobj) {...} 之中 。wait() 也是这个样子,一个线程需要释放某个 lock,也是在其获得 lock 情况下才能够释放,所以 wait() 也需要放在 synchronized(lockobj) {...} 之中 。
推荐阅读
- 绿色环保家具排行榜
- 北京环球度假区怎么去?地铁、驾车都方便,小编带你走一趟
- 什么,葡萄酒还有欧盟有机认证?
- 舌头|火腿肠吃出尖锐异物、舌头划烂出血?双汇:需要核实
- 古丈县、舌尖山水,古丈毛尖
- 淘宝、抖音、快手的流量运营逻辑!
- 细谈8种架构设计模式及其优缺点
- 常见web安全问题,SQL注入、XSS、CSRF,基本原理以及如何防御
- 一加Ace|一加官宣云耳Z2、Buds N两款耳机新品:21日与Ace同步发布
- 孕妇可以喝茶吗? 过多、过浓或影响胎儿发育
