对线程安全的质疑

Doubts on thread safety

我对 java 中的多线程处理不熟悉,现在我必须使用一些旧的 类 来实现多线程模块。我认为存在一些竞争条件问题,因为我在单线程和多线程执行之间得到不同的结果。我的主要疑惑如下:

public class Worker implements Runnable{

    final private int minIndex; // first index, inclusive
    final private int maxIndex; // last index, exclusive
    final private MyDTO dto;
    private MyService myService;

    public Worker(MyDTO dto) {
        this.minIndex = dto.getMinIndex();
        this.maxIndex = dto.getMaxIndex();
        this.dto = dto;
        myService = new MyService();

    }

    public void run() {
        int countReg = 0;
        if(!initErrors){

            try {
                Connection conn = ConnectionFactory.getConnection();
                for(int i = minIndex ; i<maxIndex; i++){
                    myService.executeCalculation(dto,conn);
                    countReg++;
                }
                conn.close();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }           
        }
    }


public class MyService{


    //It has some method to get object from the database

    public void executeCalculation(MyDTO dto,Connection conn) {

        //I do some actions and 
        RegolaDAO regolaDAO = new RegolaDAO(conn);
        MyObject obj = new MyObject(conn);
        // I use obj durin the calculation

        }   
    }
}

public class MyObject{

    Connection conn;

    public MyObject (Connection conn){
        super();
        this.conn = conn;
    }
}

我的服务是无状态对象,因此应该不会产生任何问题,而 MyObject 是有状态对象,这可能会产生问题。我的主要疑问是我在每次计算中都使用了 new 关键字 MyObject obj = new MyObject(); 这有助于我防止竞争条件。

MyObject 线程安全吗? 你能给我一些关于我的实施的建议吗?

由于 myService 未更改,您可以将其设为最终版本。

您的 dto 似乎在线程之间共享,我会检查它是否也是只读的。

还有 conn 是如何传递给 executeCalculation 的,你应该确保你没有为此使用字段。

MyObject thread safe? Can you give me some suggestion about my implementation?

因为MyObject有非final字段(myService)所以它被认为不是线程安全的。如果两个线程使用同一个 MyObject 实例,它们可以在 正确初始化之前开始使用 myService 。正如@Peter 指出的那样,使 myService 成为 final 将解决该特定问题。

查看代码,以下行正在调用其他 类 线程安全问题的候选者也是如此:

if (!initErrors) {

我不明白 initErrors 是如何定义的。如果在线程之间共享,则需要 volatileAtomicBooolean.

Connection conn = ConnectionFactory.getConnection();

ConnectionFactory 是线程安全的吗?可以多个线程同时调用吗?

myService.executeCalculation(dto, conn);

executeCalculation(...) 方法的相同问题。此外,正如@Peter 指出的那样,服务正在使用 dto 。如果服务正在对 dto 实例进行更改,则需要对其进行同步。