Java多线程入门类和接口
Thread
常用方法:
- currentThread():静态方法,返回对当前正在执行的线程对象的引用
- start():开始执行线程的方法,jvm会调用县城内的run方法
- yield():当前线程让出对当前处理器的占用,但是要注意的是,就算线程调用了yield,程序在调度时还有可能继续运行这个线程的
- sleep():使当前线程睡眠一段时间
- join():是当前线程等待另一个线程执行完毕之后再执行,内部调用的是wait方法实现的
Callable,Future与FutureTask
Callable接口
这个接口和Runnable类似,不同的是Callable有返回值,而且支持泛型
@FunctionalInterface
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
Callable一般是配合线程池工具ExecutorService使用的,ExecutorService可以使用submit方法来让一个callable接口执行
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4pw5F3vX-1638712145851)(/upload/2021/12/image-0b18fbd70fe14750a10eac9840385e2c.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XZmgtGYi-1638712145854)(C:\Users\Leoyu\AppData\Roaming\Typora\typora-user-images\image-20211201010745768.png)]
Future接口
public abstract interface Future<V> {
public abstract boolean cancel(boolean paramBoolean);
public abstract boolean isCancelled();
public abstract boolean isDone();
public abstract V get() throws InterruptedException, ExecutionException;
public abstract V get(long paramLong, TimeUnit paramTimeUnit)
throws InterruptedException, ExecutionException, TimeoutException;
}
-
cancel:试图取消一个线程的执行
并不一定能成功,因为任务可能已完成,已取消,或者一些其他因素不能取消,存在取消失败的可能。boolean类型的返回值是“是否取消成功的意思”。参数paramBoolean表示是否采用中断的方式取消线程执行
所以有时候,为了让任务能有被取消的功能,就是用callable代替Runnable。
FutureTask类
上面提到的Future接口,由一个实现类交FutureTask。FutureTask是实现的RunnableFuture接口的,而RunnableFuture接口同时继承了Runnable接口和Future接口
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
示例代码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rdBNAq5T-1638712145855)(/upload/2021/12/image-b775fc8b060e484f81a2806496183c07.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vuj4ROug-1638712145856)(C:\Users\Leoyu\AppData\Roaming\Typora\typora-user-images\image-20211201011905114.png)]
首先这个代码和上面的区别是submit方法是没有返回值的,这里实际上带用的是submit(Runnable task) 方法,而上面调用的是submit(Callable task)方法
这里是使用FutureTask直接取get取值,而上面是submit方法返回的Future去取值
FutureTask能够在高并发环境下保证任务只执行一次
FutureTask状态
/**
*
* state可能的状态转变路径如下:
* NEW -> COMPLETING -> NORMAL
* NEW -> COMPLETING -> EXCEPTIONAL
* NEW -> CANCELLED
* NEW -> INTERRUPTING -> INTERRUPTED
*/
private volatile int state;
private static final int NEW = 0;
private static final int COMPLETING = 1;
private static final int NORMAL = 2;
private static final int EXCEPTIONAL = 3;
private static final int CANCELLED = 4;
private static final int INTERRUPTING = 5;
private static final int INTERRUPTED = 6;