对线程安全的质疑
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
是如何定义的。如果在线程之间共享,则需要 volatile
或 AtomicBooolean
.
Connection conn = ConnectionFactory.getConnection();
ConnectionFactory
是线程安全的吗?可以多个线程同时调用吗?
myService.executeCalculation(dto, conn);
executeCalculation(...)
方法的相同问题。此外,正如@Peter 指出的那样,服务正在使用 dto
。如果服务正在对 dto
实例进行更改,则需要对其进行同步。
我对 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
是如何定义的。如果在线程之间共享,则需要 volatile
或 AtomicBooolean
.
Connection conn = ConnectionFactory.getConnection();
ConnectionFactory
是线程安全的吗?可以多个线程同时调用吗?
myService.executeCalculation(dto, conn);
executeCalculation(...)
方法的相同问题。此外,正如@Peter 指出的那样,服务正在使用 dto
。如果服务正在对 dto
实例进行更改,则需要对其进行同步。