`
newslxw
  • 浏览: 212201 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

多线程下谨慎对待基类(抽象类)中的成员变量

阅读更多
有这么个需求:
做开发一套在oracle和mysql中做业务数据复制,其中具体的业务还没确定,目前需要开发一套
框架,需要在业务确定后,只需做少了开发即可实现,我使用了ibatis+spring
,以后扩展时,只需增加ibatis的配置文件即可,而配置文件中的每个ID都是由以下规则生成:
业务识别码+新增/删除等统一的后缀。
如下结构:

1、DAO部分
public abstract class Base
{
   private String name;
   private String code;
   public String getName(){return name;}
   public String getCode(){return code;}
   public void setName(String name){this.name=name;}
   public void setCode(String code){this.code = code;}

   public String getInsertSqlName()
   {
       return this.code+"insert";
   }

   public abstract insert(...);
   public abstract query(...);

}

public class ADao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}
public class  BDao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}

public class CDao extends Base
{
       public map insert(...)
   {
      String sqlName = this.getInsertSqlName();
      //用ibatis操作数据库

   }

   public map query(...)
   {
      xxxxx
   }
}



2、Service部分
   根据数据库配置动态创建DAO,大概如下:
   String name=从数据库读取
    String code = 从数据库读取
    Base dao = ServFactory.getDao(name,code);
   dao.insert(xxx);
   dao.query(xxx);


3、为了重用DAO,如上面Service部分,使用ServFactory创建DAO,
   原理就是将创建的DAO放到map中,在getDao前先检查map中有没有DAO,没有则创建。

单线程运行下没问题。

但是在并发处理时,发现查询出来的数据错位了,明明查A的数据,结果返回了B的数据。

使用debug跟踪发现,DAO中的name和code会在执行insert后的query被突然改变,原来在并发下有其他请求的code被其他获取相同DAO的线程改变,导致最后执行的SQL不是预期的SQL。

解决方法有2:
1、不缓存DAO,每次创建个新DAO

2、不适用Base的成员变量,直接将name和code通过参数传入到insert和query中

我选择了后者。
分享到:
评论

相关推荐

    基类线程源代码

    在实际项目中,这样的线程基类可以被子类化,以满足特定的需求。例如,你可以创建一个继承自CSimpleThread的子类,并在子类中重写`Run()`方法,以执行特定的业务逻辑。 为了更好地理解这个类的工作原理,你需要查看...

    Java抽象类和接口 Java全栈

    在Java编程语言中,抽象类和接口是两个重要的概念,它们用于实现代码的多态性和模块化设计。本文将深入探讨这两个概念,以及它们在Java全栈开发中的应用。 首先,我们来理解抽象类(Abstract Class)。抽象类是不能...

    教学视频-抽象类&接口

    5. **接口与抽象类的区别**:对比两者在使用上的差异,包括继承的数量限制(一个类只能继承一个抽象类,但可以实现多个接口)和成员类型(抽象类可有实例变量,接口则没有)。 6. **适配器模式**:可能会介绍如何...

    JAVA类的方法调用和变量

    抽象类不能被实例化,它们通常作为其他类的基类,提供继承的结构。 3. **静态类**:静态类,也称为工具类,通常包含静态方法和静态变量。它们不能包含非静态成员,也不能被实例化。静态类中的方法可以通过类名直接...

    Java类变量和方法.doc

    `volatile`关键字用于修饰多线程环境中的变量,确保其可见性和有序性。实例变量与类变量相对,每个对象都有独立的副本。 方法是类中的行为,分为实例方法和类方法(静态方法)。`static`修饰的方法是类方法,它在类...

    多线程测试(wxWidgets)

    在C++编程中,多线程是一个核心概念,它允许程序同时执行多个任务,从而提高系统效率和响应性。在现代计算机系统中,多核处理器的普及使得多线程技术成为充分利用硬件资源的关键。本教程将重点介绍如何在C++环境中,...

    MFC多线程例程

    在`vc6`环境下创建MFC多线程项目,你需要选择MFC AppWizard,并在向导中选择"单文档"或"多文档"应用程序,然后在工程设置中选择"多线程"选项。 为了使多线程协同工作,MFC提供了一些同步机制,如`CSemaphore`(信号...

    多线程实例

    在IT领域,多线程是程序设计中一个关键的概念,特别是在C++这样的面向对象编程语言中。多线程允许程序同时执行多个独立的任务,从而提高了系统资源的利用率和程序的执行效率。本实例集中展示了如何在C++环境中利用多...

    java基础部分的笔记,包含抽象,特征,映射,流,线程,反射等

    抽象类用作其他类的基类,接口则提供了多继承的功能,使得类可以实现多个接口,从而实现多种行为。 2. **特征**:在Java中,特征通常指的是类的属性(成员变量)和行为(方法)。类的特征定义了对象的状态和操作。...

    C++面向对象多线程编程

    根据提供的标题“C++面向对象多线程编程”和描述“C++面向对象多线程编程,一本经典的学习资料,很好的”,我们可以理解这是一本关于使用C++进行面向对象及多线程编程的经典教程。虽然具体内容没有给出,但从标题和...

    用MFC编写VC多线程程序

    标题中的“用MFC编写VC多线程程序”是指在Microsoft Visual C++(VC)开发环境中,利用MFC(Microsoft Foundation Classes)库来构建多线程应用。MFC是微软提供的一个C++类库,它封装了Windows API,使得开发者能更...

    c++ 面向对象多线程编程

    在C++中,抽象类通常包含纯虚函数,不能实例化,用于作为其他类的基类。 接下来,我们转向多线程编程。多线程是在单个程序中同时执行多个独立的执行流,从而提高程序的并发性和效率。C++11引入了对多线程的支持,...

    视频采集的基类

    在"CaptureVideo.cpp"和"CaptureVideo.h"这两个文件中,通常cpp文件包含了类的实现细节,而h文件则是类的声明,包括类的定义、成员函数和变量等。以下是可能包含在这些文件中的关键知识点: 1. **类设计**:`...

    电信面试题

    - 抽象类可以有普通成员变量和静态成员变量。 - 接口只有公共静态常量。 3. **方法**: - 抽象类可以包含抽象方法(没有方法体)和非抽象方法(有方法体)。 - 接口中所有方法默认都是抽象的,且必须是公共的,...

    介绍了VB6中的物件导向概念,共享内存、多线程等示例

    在VB6中,虽然没有内置的抽象类概念,但可以通过定义纯虚方法(MustOverride)来实现类似的效果。 共享内存是一种多线程间的通信方式,允许不同线程访问同一块内存区域。在VB6中,可以使用全局变量或者模块级别的...

    java基础思维导图 全套 到多线程 思维导图

    同时,抽象类是包含抽象方法(没有实现的方法)的类,可以作为其他类的基类,提供部分实现。 在Java中,异常处理是一个重要的话题。使用try-catch-finally结构可以捕获和处理运行时错误,保证程序的健壮性。异常...

    C-中属性和字段(变量)的区别

    3. **线程同步**:属性可以通过在`set`访问器中使用`lock`语句来实现线程同步,确保多线程环境下的数据一致性。 4. **抽象性**:属性可以被声明为抽象的,这意味着在基类中声明属性而不提供具体实现,留给派生类...

    软件编程词汇表(一些编程词汇的解释)

    受保护区域是指在多线程环境中,为了防止并发访问而导致的数据不一致性,而使用同步机制(如锁)保护的代码段。通过确保每次只有一个线程可以访问受保护区域,可以有效地避免竞态条件。 #### 33. 堆 (Heap) 堆是...

    java程序语言设计的基础复习

    8. **volatile**: 指定该变量具有易变性,可以被多线程访问和修改。它确保了变量的可见性和一定程度的原子性,但并不保证完全的原子性操作。 #### 四、总结 通过以上介绍,我们可以看到Java提供了丰富的特性和机制...

Global site tag (gtag.js) - Google Analytics