run方法,无返回值
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
// 启动线程
new Thread(new Runnable() {
@Override
public void run() {
while(true){
try {
System.out.println(11);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
call方法,返回传入的泛型
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;
}
取消、查询是否完成、获取结果、设置结果操作。get方法会阻塞,直到任务返回结果
/**
* @see FutureTask
* @see Executor
* @since 1.5
* @author Doug Lea
* @param <V> The result type returned by this Future's <tt>get</tt> method
*/
public interface Future<V> {
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when <tt>cancel</tt> is called,
* this task should never run. If the task has already started,
* then the <tt>mayInterruptIfRunning</tt> parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task. *
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns <tt>true</tt> if this task was cancelled before it completed
* normally.
*/
boolean isCancelled();
/**
* Returns <tt>true</tt> if this task completed.
*
*/
boolean isDone();
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
*/
V get() throws InterruptedException, ExecutionException;
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the computed result
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
继承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();
}
实现RunnableFuture
接口
public class FutureTask<V> implements RunnableFuture<V>
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() {
long start = System.currentTimeMillis();
while(true){
// 计算线程启动的秒数
float seconds = (System.currentTimeMillis() - start) / 1000f;
System.out.println(String.format("%.2f", seconds));
// 线程中断时,中断线程
if(Thread.currentThread().isInterrupted()){
System.out.println("interrupted");
break;
}
// 运行超过15s时,结束线程
if(Float.compare(seconds, 15f) > 0){
System.out.println("over");
break;
}
}
return 1;
}
});
new Thread(futureTask).start();
try {
// FutureTask.get() 方法的几种情况:
// 阻塞主线程,直到结果返回
System.out.println(futureTask.get());
// 阻塞主线程,等待5秒线程未运行结束,抛出TimeoutException
System.out.println(futureTask.get(5, TimeUnit.SECONDS));
// 阻塞主线程,等待20秒,线程提前运行结束会立即返回
System.out.println(futureTask.get(20, TimeUnit.SECONDS));
// 阻塞主线程,直到结果返回,中断线程,抛出InterruptedException
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
futureTask.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
System.out.println(futureTask.get());
} catch (InterruptedException e) {
System.out.println("get exception: InterruptedException");
} catch (ExecutionException e) {
System.out.println("get exception: ExecutionException");
} catch (TimeoutException e) {
System.out.println("get exception: TimeoutException");
}
System.out.println("main thread over");
Java中的Runnable、Callable、Future、FutureTask的区别与示例_Mr.Simple的专栏-CSDN博客
通过调用Thread.interrupt()
改变中断状态值,在Thread.run()
方法中通过Thread.currentThread().isInterrupted()
判断状态值,中断线程
if(Thread.currentThread().isInterrupted()){
System.out.println("interrupted");
break;
}
Thread.sleep
时调用Thread.interrupt()
,立即抛出InterruptedException
-
状态值不会设置成功,故即使根据中断状态值做出了中断处理,线程会继续运行
-
FutrueTask.get()
会立即抛出Exception
修改 FutureTask 中的例子,每次间隔500ms打印,在10s处中断线程
FutureTask<Integer> futureTask = new FutureTask<>(new Callable<Integer>() {
@Override
public Integer call() {
long start = System.currentTimeMillis();
while(true){
float seconds = (System.currentTimeMillis() - start) / 1000f;
System.out.println(String.format("%.2f", seconds));
if(Thread.currentThread().isInterrupted()){
System.out.println("interrupted");
break;
}
if(Float.compare(seconds, 15f) > 0){
System.out.println("over");
break;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
System.out.println("sleep exception: InterruptedException");
}
}
return 1;
}
});
new Thread(futureTask).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(10000);
futureTask.cancel(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
System.out.println(futureTask.get(20, TimeUnit.SECONDS));
} catch (InterruptedException e) {
System.out.println("get exception: InterruptedException");
} catch (ExecutionException e) {
System.out.println("get exception: ExecutionException");
} catch (TimeoutException e) {
System.out.println("get exception: TimeoutException");
} catch (Exception e) {
System.out.println("get exception: Exception");
}
System.out.println("main thread over");
打印结果
...
9.69
sleep exception: InterruptedException
10.00
get exception: Exception null
main thread over
10.52
...
15.11
over