美文网首页
关于线程安全问题

关于线程安全问题

作者: bigdata张凯翔 | 来源:发表于2020-08-16 11:00 被阅读0次

一、 通过线程池创建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>();
        
        //解决方案。。。

    }

}

相关文章

  • Java 面试系列:线程安全之 synchronized 和 R

    前面我们介绍了很多关于多线程的内容,在多线程中有一个很重要的课题需要我们攻克,那就是线程安全问题。线程安全问题指的...

  • Java线程安全

    线程安全问题的概述 线程安全问题的代码实现 线程安全问题产生的原理 解决线程安全问题_同步代码块 同步代码块:sy...

  • 7.2 Handler消息传递机制

    简介:handler消息处理者,用来发生和处理消息,用于解决线程安全问题; 线程安全问题:多线程导致线程安全问题,...

  • 同步监视器锁定的释放问题

    在任何编程语言中,事关线程安全问题非常重要,而同步监测器是解决java多线程安全问题的关键,关于监测器锁定...

  • 线程的基本语法

    线程同步[解决线程安全问题] 解决线程安全问题 线程同步方式一:同步代码 语法基本 synchronized (同...

  • 五 异常与多线程——第三节 线程同步机制

    1、线程安全问题的概述 多线程访问了共享的数据,就会产生线程安全问题 2、线程安全问题的代码实现 输出:会出现重复...

  • 关于线程安全问题

    一、 通过线程池创建A,B,C三个子线程,并设置A子线程执行1秒;B子线程执行3秒; C子线程执行7秒。要求:①主...

  • 线程安全问题

    线程安全问题 本篇主要讲解 线程安全问题,演示什么情况下会出现线程安全问题,以及介绍了 Java内存模型 、vol...

  • 线程安全问题的几种解决办法

    title: 线程安全问题date: 2019/04/01 17:13 线程安全问题是由于多个线程同时操作同一全局...

  • volatile关键字

    线程安全问题 Java多线程带来的一个问题是数据安全问题,判断一段Java代码是否有线程安全问题可从以下几点入手:...

网友评论

      本文标题:关于线程安全问题

      本文链接:https://www.haomeiwen.com/subject/bcdtjktx.html