gpt4 book ai didi

java - 多个Thread可以进入InsertDAO吗?

转载 作者:行者123 更新时间:2023-11-30 09:11:28 25 4
gpt4 key购买 nike

我有一个 Client 类调用 MyService 类的 execute 方法。此方法将依次调用 InsertDAO 类。此 InsertDAO 具有带有实例变量的状态。这仅从 MyService 类的 execute 方法调用。不能直接调用 InsertDAO 类。

我没有创建任何线程,但我的 App Server 可能会在 Client 类上创建线程。现在,我想了解这将如何影响 InsertDAO 类。

  1. 多个线程可以同时访问 InsertDAO 的一个对象吗? -- 是/否
  2. 当线程在 Client 类上生成时,MyService 类的同一个实例将提供给 Client 上的所有线程。然后每个线程都应该调用 MyService 的“执行”方法。这意味着每个线程都有自己的 InsertDAO 实例(我在 MyService 类的 execute 方法中创建 InsertDAO 对象)。如果是这样,多个线程不能同时进入 InsertDAO。我的理解正确吗?
  3. 多个线程如何进入 MyService.execute() -- 一些解释,如果这是真的。
  4. 多个线程如何进入 InsertDAO 类? -- 一些解释,如果这是真的。
  5. 如何在不影响性能的情况下使其成为线程安全的?

请专家们谈谈你的看法。下面是我的代码。

//code starts here
public class Client{
public void performExecution(){
InvoiceVO createInvoiceVO = new InvoiceVO();
MyService service = new MyService();
createInvoiceVO = service.execute(createInvoiceVO);
//retrieve successful/failure information from createInvoiceVO
}
}

public class MyService{
public InvoiceVO execute(InvoiceVO createInvoiceVO){
InsertDAO insertDAO = new InsertDAO();
insertDAO.process(createInvoiceVO);
}
}

public class InsertDAO{
private List<LineItem> lineItemsList = new ArrayList<LineItem>();
private List<TaxVO> taxVOList = new ArrayList<TaxVO>();
private Connection connection = null;

public InvoiceVO process(InvoiceVO createInvoiceVO){
this.lineItemsList = createInvoiceVO.getLineItemsList();
this.taxVOList = createInvoiceVO.getTaxVOList();

connection = getConnection();
//insert tax vo objects
insertTaxVOObjects(taxVOList);

//insert line items
insertLineItems(this.lineItemsList);

//commit operation

//close connection
closeConnection();
}

private void insertTaxVOObjects(List<TaxVO> taxVOList){
//code to insert TaxVO objects
}

private void insertLineItems(List<LineItem> lineItemsList){
//code to insert LineItem objects
}

private void getConnection(){
//code to return connection
}

private void closeConnection(){
//code to close connection
}
}

最佳答案

你问的问题不对,线程不进入类,它们进入对象;我们需要查看对象的生命周期以及何时创建线程。

现在我不了解您的执行环境 - 我不清楚线程是在哪里创建的,但我假设以某种方式创建了客户端对象,并且每个对象的 performExecution() 方法可能在其自己的线程上运行。现在的问题是,您的任何一个 InsertDAO 对象是否可能同时从两个线程访问,或者两个 InsertDAO 对象是否可能共享一些数据,因此两个线程可能会发生干扰。

现在我们首先注意到每个 InsertDAO 对象都是独立的,它们有变量但这些变量不是静态的。例如你有

this.lineItemsList

因此数据由单个对象实例拥有,没有其他对象(可能在另一个线程中)可以看到附加到 this 的数据。请注意,如果您有静态 数据,所有实例都可以看到它,您就会遇到问题。第一条规则:没有静态数据,除非您使用同步访问来保护它。

您遇到潜在问题的一个地方是您请求连接。现在连接通常是池化的,我们真的不想为每个请求都打开一个连接,而是我们从池中获取一个连接并在我们使用它时返回。整个想法是线程共享同一个池。所以这里的一般原则是,你的 InsertDAO 对象使用的任何它们没有作为成员变量的东西都必须是线程安全的,也就是说作者必须在多线程访问的期望中编写它它。共享池:作者必须使用某种同步访问。规则 2:看看您使用的是什么以及您自己的代码。

最后一点,两个线程可以共享一个 InsertDAO 对象吗?要回答这个问题,请查看您是如何创建它们的:

public InvoiceVO execute(InvoiceVO createInvoiceVO){
InsertDAO insertDAO = new InsertDAO();
insertDAO.process(createInvoiceVO);
}

在这里你创建对象,调用它的方法并返回(隐式释放对象),没有其他线程可以看到这个,它在你的堆栈上是本地的。因此我们知道只有一个线程使用一个 InsertDAO 对象。规则三:由调用者决定有多少线程可以看到一个对象。在您的情况下,您已经确保了一个线程。

关于java - 多个Thread可以进入InsertDAO吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22087212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com