模板方法中的线程安全问题

这篇具有很好参考价值的文章主要介绍了模板方法中的线程安全问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、线程安全?

是否存在临界区,共享的变量,会被不同线程写入

那么模板方法里面基类的成员变量或者方法就会存在线程安全问题

2、excel 

模板方法中的线程安全问题

 

AbstractExcelSheet

业务数据和excel 逻辑 解耦

让data 可以 在service 层之间set进来

这样excel的相关类不用添加到 spring 容器中

模板方法中的线程安全问题

 

public abstract class AbstractExcelSheet<T> {
    private XSSFWorkbook workbook;

    private XSSFSheet sheet;

    /**
     * 写入数据
     */
    private List<T> data;

    public void setData(List<T> data) {
        this.data = data;
    }

    /**
     * 获取当前类的sheet对象
     *
     * @return sheet对象
     */
    public XSSFSheet getSheet() {
        return sheet;
    }

    /**
     * 设置sheet对象
     *
     * @param sheet sheet对象
     */
    public void setSheet(XSSFSheet sheet) {
        this.sheet = sheet;
    }

    /**
     * 获取所属的excel对象
     *
     * @return excel对象
     */
    public XSSFWorkbook getWorkbook() {
        return workbook;
    }

    /**
     * 设置excel对象
     *
     * @param workbook excel对象
     */
    public void setWorkbook(XSSFWorkbook workbook) {
        this.workbook = workbook;
    }

    /**
     * 创建sheet页基本信息
     */
    public abstract void createSheet();

    /**
     * 在子类重写
     *
     * @return 标题列
     */
    public abstract List<String> getTitles();

    /**
     * 生成sheet标题列,此方法不必重写
     */
    public void createTitleRow() {
        List<String> titles = getTitles();
        // 得到行
        XSSFRow titleRow = getSheet().createRow(0);
        for (int i = 0; i < titles.size(); i++) {
            XSSFCell cell = titleRow.createCell(i);
            cell.setCellStyle(ExportExcelUtil.getTitleStyle(getWorkbook()));
            cell.setCellValue(titles.get(i));
        }
        // 设置行高
        titleRow.setHeight((short) 460);
    }

    /**
     * 添加导出excel的内容
     *
     * @param data 导出数据
     */
    public abstract void createDataRow(List<T> data);

    /**
     * writeSheetData
     */
    public void writeSheetData() {
        // 创建表单 sheet
        createSheet();
        // sheet 设置表头内容(第一行内容)
        createTitleRow();
        // 从数据库取数并写到文件中
        createDataRow(data);
    }

    /**
     * 写入一行 sheet 数据
     *
     * @param rowIndex sheet 写入 行索引
     * @param data sheet 实体数据
     * @param enumValues sheet 表头标题
     * @param <S> 泛型
     */
    protected <S> void writeRowData(int rowIndex, S data, SheetTitleEnum[] enumValues) {
        XSSFRow row = getSheet().createRow(rowIndex);
        int colIndex = 0;
        XSSFCell cell = row.createCell(colIndex);
        for (SheetTitleEnum enumValue : enumValues) {
            String cellValue = ExportExcelUtil.getCellValue(data, enumValue);
            cell.setCellValue(cellValue);
            cell = row.createCell(++colIndex);
        }
    }
}

BusiPackageResultExcelSheet

业务知识包检查结果.xlsx 业务知识包检查结果 sheet

 

public class BusiPackageResultExcelSheet<T> extends AbstractExcelSheet<T> {
    private final static String SHEET_NAME = "业务知识包检查结果";

    @Override
    public void createSheet() {
        this.setSheet(this.getWorkbook().createSheet(SHEET_NAME));
    }

    @Override
    public List<String> getTitles() {
        return BusiPackageResultSheetTitleEnum.titles;
    }

    @Override
    public void createDataRow(List<T> data) {
        // 表头 rowIndex = 0, 所以 rowIndex = 1
        int rowIndex = 1;
        SheetTitleEnum[] enumValues = BusiPackageResultSheetTitleEnum.values();
        for (T dataEntry : data) {
            // 写入行数据
            writeRowData(rowIndex++, dataEntry, enumValues);
        }
    }
}

BusiPkgRuleResultExcelSheet

业务知识包检查结果.xlsx 规则检查结果 sheet
public class BusiPkgRuleResultExcelSheet<T> extends RuleResultExcelSheet<T> {
    @Override
    public void createDataRow(List<T> data) {
        // 表头 rowIndex = 0, 所以 rowIndex = 1
        int rowIndex = 1;
        for (T dataEntry : data) {
            // 写入行数据
            writeRowData(rowIndex++, dataEntry, RuleResultSheetTitleEnum.values());
        }
    }
}

 

RuleResultExcelSheet

规则检查结果.xlsx 规则检查结果 sheet
public class RuleResultExcelSheet<T> extends AbstractExcelSheet<T> {
    private final static String SHEET_NAME = "规则检查结果";

    @Override
    public void createSheet() {
        this.setSheet(this.getWorkbook().createSheet(SHEET_NAME));
    }

    /**
     * 表头内容
     *
     * @return 表头内容
     */
    @Override
    public List<String> getTitles() {
        return RuleResultSheetTitleEnum.titles;
    }

    @Override
    public void createDataRow(List<T> data) {
        // 表头 rowIndex = 0, 所以 rowIndex = 1
        int rowIndex = 1;
        SheetTitleEnum[] enumValues = RuleResultSheetTitleEnum.values();
        for (T dataEntry : data) {
            // 写入行数据
            writeRowData(rowIndex++, dataEntry, enumValues);
        }
    }
}

上面的设计 大部分的方法都是在基类实现了

当excel的表头不一样,是在子类实现的

3、线程安全问题点

所有的成员变量都有可能被其他线程争抢,

比如 线程1 setData data1 

但是此时如果线程1 excel 还没导出成功,

线程2进来了 setData data2

把线程1的 data 覆盖了

其实还有很多线程问题,因为多线程是不可控的

4、解决

 service 在的调用 excel 实现类的时候,变成局部变量

在单应用中 合理运用 synchronized 、ReentrantLock、 ThreadLocal 原子应用

分布式 合理运用 redis 锁

两种运用,注意死锁问题文章来源地址https://www.toymoban.com/news/detail-434123.html

到了这里,关于模板方法中的线程安全问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java多线程 - 线程安全和线程同步解决线程安全问题

    线程安全问题指的是: 多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,称为线程安全问题。 举例: 取钱模型演示 需求:小明和小红是一对夫妻,他们有一个共同的账户,余额是10万元。 如果小明和小红同时来取钱,而且2人都要取钱10万元,可能出现什么问

    2023年04月15日
    浏览(38)
  • 【多线程】线程安全问题

    我们先来看一段代码: 这段代码是对 count 自增 10w 次,随之的打印结果 count = 100000,相信也没有任何的歧义,那么上述代码是否能优化呢?能否让速度更快呢? 相信学习到这里大家都会想到用多线程,可以搞两个线程,每个线程执行 5w 次自增就行了,甚至还可以搞五个线程

    2024年02月01日
    浏览(33)
  • 【多线程】线程安全 问题

    多次执行的结果: 两个线程各 加了 50000 次, 但最终结果都不是我们预期的 100000, 并且相差甚远。 操作系统调度线程是随机的(抢占式),正因为这样的随机性,就可能导致程序的执行出现一些 bug。 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该

    2024年02月09日
    浏览(29)
  • java基础之线程安全问题以及线程安全集合类

    当多个线程同时访问同一个临界资源时,原子操作可能被破坏,会导致数据丢失, 就会触发线程安全问题 临界资源: 被多个线程同时访问的对象 原子操作: 线程访问临界资源的过程中不可更改和缺失的操作 互斥锁 每个对象都默认拥有互斥锁, 该锁默认不开启. 当开启互斥锁之后

    2024年01月18日
    浏览(54)
  • Java多线程之线程安全问题

    我们知道操作系统中线程程的调度是抢占式执行的, 宏观上上的感知是随机的, 这就导致了多线程在进行线程调度时线程的执行顺序是不确定的, 因此多线程情况下的代码的执行顺序可能就会有无数种, 我们需要保证这无数种线程调度顺序的情况下, 代码的执行结果都是正确的

    2023年04月17日
    浏览(45)
  • Spring中的Bean是线程安全的吗?

    其实,Spring 中的 Bean 是否线程安全,其实跟 Spring 容器本身无关。Spring 框架中没有提供线程安全的策略,因此,Spring 容器中在的 Bean 本身也不具备线程安全的特性。咱们要透彻理解这个结论,我们首先要知道 Spring 中的 Bean 是从哪里来的。 在 Spring 容器中,除了很多 Spring 内

    2024年02月11日
    浏览(37)
  • 【多线程】线程安全问题原因与解决方案

    目录 线程安全的概念 线程不安全示例 线程不安全的原因      多个线程修改了同一个变量     线程是抢占式执行的     原子性     内存可见性     有序性 线程不安全解决办法  synchronized -监视器锁monitor lock     synchronized 的特性         互斥         刷新内

    2024年02月06日
    浏览(37)
  • java 线程安全问题 三种线程同步方案 线程通信(了解)

    线程安全问题指的是,多个线程同时操作同一个共享资源的时候,可能会出现业务安全问题。 下面代码演示上述问题,先定义一个共享的账户类: 在定义一个取钱的线程类 最后,再写一个测试类,在测试类中创建两个线程对象 某个执行结果: 为了解决前面的线程安全问题,

    2024年02月09日
    浏览(43)
  • java中的线程不安全和实例解析,网络安全多态实现原理

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新网络安全全套学习资料》

    2024年04月27日
    浏览(43)
  • 【Java】线程安全问题

    在之前的文章中,已经介绍了关于线程的基础知识。 我的主页: 🍆🍆🍆爱吃南瓜的北瓜 欢迎各位大佬来到我的主页进行指点 一同进步!!! 我们创建两个线程t1和t2,对静态变量count执行++操作各50000次。 我们的预期结果是100000。但是当两个线程分别执行++操作时最后的结果

    2024年04月10日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包