FutureTask并发详解,通俗易懂
最近做项目,使用到了FutureTask和主线程并发,应用到实际中还是挺实用的,特在此总结一下。
有不对之处,忘各位多多指出。
1 package com.demo;
2
3 import java.util.concurrent.Callable;
4 import java.util.concurrent.FutureTask;
5
6 public class FutureTaskTest {
7
8 public static void main(String[] args) throws Exception {
9 for (int i = 0; i < 10; i++) {
10 long currentTimeMillis = System.currentTimeMillis();
11 FutureTask<String> future1 = new FutureTask<>(new MyTaskA());
12 new Thread(future1).start();// 一定要先开启线程,如果主线程在开启线程前调用,就没了并发的效果,可以自行测试
13 Thread.sleep(100);// 主线程耗时100ms
14 String r1 = future1.get();
15 System.out.println(r1);
16 System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
17 }
18 }
19
20 static class MyTaskA implements Callable<String> {
21 @Override
22 public String call() throws Exception {
23 Thread.sleep(50);// 并发线程耗时50ms
24 return "testA";
25 }
26 }
27
28 }
20-26行创建一个任务MyTaskA,实现的是Callable,主要是为了获取返回值(关于如何创建线程,这里就不在赘述);
11行创建FutureTask;
12行启动线程:此时任务MyTaskA就已经开始执行;
13行主线程执行耗时100ms的任务;
14行FutureTask获取返回值,该方法是会等待任务完成然后获取到返回值。
输出结果如下:
testA 0-----101ms testA 1-----100ms testA 2-----100ms testA 3-----100ms testA 4-----100ms testA 5-----100ms testA 6-----100ms testA 7-----100ms testA 8-----100ms testA 9-----100ms
上面就是一个线程和主线程并发执行,下面再看一个两个线程和主线程并发,其实差别不大
1 package com.demo;
2
3 import java.util.concurrent.Callable;
4 import java.util.concurrent.FutureTask;
5
6 public class FutureTaskTest {
7
8 public static void main(String[] args) throws Exception{
9 for (int i = 0; i < 10; i++) {
10 long currentTimeMillis = System.currentTimeMillis();
11
12 FutureTask<String> futureA = new FutureTask<>(new MyTaskA());
13 FutureTask<String> futureB = new FutureTask<>(new MyTaskB());
14 new Thread(futureA).start();
15 new Thread(futureB).start();
16
17 Thread.sleep(100);
18 System.out.println(futureA.get()+"---"+futureB.get());
19 System.err.println(i+"-----"+String.valueOf(System.currentTimeMillis()-currentTimeMillis)+"ms");
20 }
21 }
22 static class MyTaskA implements Callable<String>{
23 @Override
24 public String call() throws Exception {
25 Thread.sleep(50);//并发线程耗时50ms
26 return "testA";
27 }
28 }
29 static class MyTaskB implements Callable<String>{
30 @Override
31 public String call() throws Exception {
32 Thread.sleep(50);
33 return "testB";
34 }
35 }
36
37
38 }
执行结果如下
testA---testB 0-----103ms testA---testB 1-----100ms testA---testB 2-----100ms testA---testB 3-----100ms testA---testB 4-----100ms testA---testB 5-----101ms testA---testB 6-----100ms testA---testB 7-----101ms testA---testB 8-----100ms testA---testB 9-----101ms
上面使用Thread启动的FutureTask,咱们也可以用线程池,代码如下
package com.demo;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class FutureTaskTest {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
long currentTimeMillis = System.currentTimeMillis();
ExecutorService executorService = Executors.newFixedThreadPool(2);
Future<String> futureA = executorService.submit(new MyTaskA());
Future<String> futureB = executorService.submit(new MyTaskB());
Thread.sleep(100);
System.out.println(futureA.get() + "---" + futureB.get());
System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
executorService.shutdown();//注意:用完之后一定要关闭线程池
}
}
static class MyTaskA implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(50);// 并发线程耗时50ms
return "testA";
}
}
static class MyTaskB implements Callable<String> {
@Override
public String call() throws Exception {
Thread.sleep(50);
return "testB";
}
}
}
输出结果如下
testA---testB 0-----104ms testA---testB 1-----101ms testA---testB 2-----101ms testA---testB 3-----101ms testA---testB 4-----100ms testA---testB 5-----102ms testA---testB 6-----101ms testA---testB 7-----101ms testA---testB 8-----101ms testA---testB 9-----101ms


浙公网安备 33010602011771号