怀疑线程安全

时间:2015-01-13 10:40:19

标签: java multithreading

我对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线程安全吗? 你能给我一些关于我实施的建议吗?

2 个答案:

答案 0 :(得分:1)

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

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

另外conn如何传递给executeCalculation,你应该确保你没有使用字段。

答案 1 :(得分:0)

  

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

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

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

if (!initErrors) {

我不知道如何定义initErrors。如果在线程之间共享,则需要volatileAtomicBooolean

Connection conn = ConnectionFactory.getConnection();

ConnectionFactory线程安全吗?多个线程可以一次调用吗?

myService.executeCalculation(dto, conn);

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