一、 通过线程池创建A,B,C三个子线程,并设置A子线程执行1秒;B子线程执行3秒; C子线程执行7秒。
要求:①主线程等待接收子线程执行结果后再执行后续处理。② 在①的基础上,如果子线程执行时间超过5秒,则主线程不再等待子线程结果,直接执行后续流程。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
/**
*
* 通过线程池创建A,B,C三个子线程,并设置A子线程执行1秒;B子线程执行3秒; C子线程执行7秒。
* 要求:①主线程等待接收子线程执行结果后再执行后续处理。
* ② 在①的基础上,如果子线程执行时间超过5秒,则主线程不再等待子线程结果,直接执行后续流程。
*
*/
public class Subject2 {
public static void main(String[] args) {
// 创建三个任务
List<FutureTask<String>> futureTasks = new ArrayList<>();
// Task A 执行1s
FutureTask<String> taskA = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(1000L);
long end = System.currentTimeMillis();
return "Task A done, 耗时:" + (end - start);
}
});
futureTasks.add(taskA);
// Task B 执行3s
FutureTask<String> taskB = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(3000L);
long end = System.currentTimeMillis();
return "Task B done, 耗时:" + (end - start);
}
});
futureTasks.add(taskB);
// Task C 执行7s
FutureTask<String> taskC = new FutureTask<String>(new Callable<String>() {
@Override
public String call() throws Exception {
long start = System.currentTimeMillis();
Thread.sleep(7000L);
long end = System.currentTimeMillis();
return "Task C done, 耗时:" + (end - start);
}
});
futureTasks.add(taskC);
// 创建线程池后,依次的提交任务执行
ExecutorService executorService = Executors.newCachedThreadPool();
for (FutureTask<String> futureTask : futureTasks) {
executorService.submit(futureTask);
}
for (FutureTask<String> futureTask : futureTasks) {
try {
// System.out.println(futureTask.get());//依次等待所有task执行完毕
System.out.println(futureTask.get(5, TimeUnit.SECONDS)); // 如果子线程执行时间超过5秒,则主线程不再等待子线程结果,直接执行后续流程。
} catch (InterruptedException e) {
System.out.println("任务执行中断...");
} catch (ExecutionException e) {
System.out.println("任务执行出错...");
} catch (TimeoutException e) {
System.out.println("任务执行超时...");
}
}
executorService.shutdown();
System.out.println("-----------所有task执行完成!------------");
System.out.println("-----------主线程执行开始------------");
}
}
二、 请编写程序证明ArrayList是非线程安全的。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
/**
*
* 请编写程序证明ArrayList是非线程安全的。
*
*/
public class Subject2 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
//启动30个线程,同时往ArrayList添加值
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
@Override
public void run() {
list.add(UUID.randomUUID().toString().substring(0, 8));
System.out.println(list);
}
}).start();
}
//上面代码执行过程,会抛出异常:java.util.ConcurrentModificationException
//解决方案有很多种,核心思路就是防止ArrayList并发修改
//解决方案1.通过Collections.synchronizedList()进行同步执行
//List<String> list = Collections.synchronizedList(new ArrayList<String>());
//解决方案2.使用CopyOnWriteArrayList代替ArrayList
//List<String> list = new CopyOnWriteArrayList<String>();
//解决方案。。。
}
}
网友评论