在 Java (Spring) 中使用线程 Id 避免竞争条件?
Avoiding race conditions using thread Id in Java (Spring)?
我有一个 Spring 引导网络应用程序。其中一项服务具有生成 CSV 文件并将其保存到磁盘的方法。然后此方法将文件位置传递给另一种方法,该方法通过电子邮件发送 CSV 文件,然后将其从磁盘中删除。为了避免并发问题,我决定将线程 Id 添加到文件名中,如下所示:
@Service
public class ReportService {
@Autowired
private ReportRepository serviceRepository;
public List<item> generateReport(Timestamp minTime, Timestamp maxTime) {
// some code to retrieve items list.
String reportTitle = "report-" + Long.toString(Thread.currentThread().getId()) + ".csv";
CsvFileWriter report = new CsvFileWriter(reportTitle);
File file = report.writeCsvFile(data);
File[] attachments = { file };
sendReportViaEmail("Please find monthly report attached.", attachments);
return items;
}
private void sendReportViaEmail(String body, File[] attachments) {
// This method sends CSV via email and then delete the 'attachments' from disk.
}
}
到目前为止它似乎在工作。我想知道的是,在我的情况下,这是否是避免竞争条件的好方法。更具体地说,
- 如果有对使用此服务的 api 资源的并发请求,每个请求是否由具有唯一线程 ID 的单独线程处理?
- 是否总是在与调用
generateReport()
的线程相同的线程中调用 sendReportViaEmail()
?
您所做的会奏效,因为 Thread
的 ID 保证在 JVM 中是唯一的。
按照评论中的建议使用 currentTomeMilis
不是 一个好主意,因为这不能保证是唯一的(两个线程可能同时调用它时间并得到完全相同的值)。
如果您想使用 built-in 工具来执行此操作,请查看 File.createTempFile()
。但是请注意,实现(至少在 Oracle 1.7 中)取决于随机数,并且在两个线程同时访问它的情况下 和 获得相同的随机数(不太可能但可能),该方法将抛出 IOException
.
另一个方法将在同一个线程中调用,如果您调用它...好吧,从线程中调用。
我有一个 Spring 引导网络应用程序。其中一项服务具有生成 CSV 文件并将其保存到磁盘的方法。然后此方法将文件位置传递给另一种方法,该方法通过电子邮件发送 CSV 文件,然后将其从磁盘中删除。为了避免并发问题,我决定将线程 Id 添加到文件名中,如下所示:
@Service
public class ReportService {
@Autowired
private ReportRepository serviceRepository;
public List<item> generateReport(Timestamp minTime, Timestamp maxTime) {
// some code to retrieve items list.
String reportTitle = "report-" + Long.toString(Thread.currentThread().getId()) + ".csv";
CsvFileWriter report = new CsvFileWriter(reportTitle);
File file = report.writeCsvFile(data);
File[] attachments = { file };
sendReportViaEmail("Please find monthly report attached.", attachments);
return items;
}
private void sendReportViaEmail(String body, File[] attachments) {
// This method sends CSV via email and then delete the 'attachments' from disk.
}
}
到目前为止它似乎在工作。我想知道的是,在我的情况下,这是否是避免竞争条件的好方法。更具体地说,
- 如果有对使用此服务的 api 资源的并发请求,每个请求是否由具有唯一线程 ID 的单独线程处理?
- 是否总是在与调用
generateReport()
的线程相同的线程中调用sendReportViaEmail()
?
您所做的会奏效,因为 Thread
的 ID 保证在 JVM 中是唯一的。
按照评论中的建议使用 currentTomeMilis
不是 一个好主意,因为这不能保证是唯一的(两个线程可能同时调用它时间并得到完全相同的值)。
如果您想使用 built-in 工具来执行此操作,请查看 File.createTempFile()
。但是请注意,实现(至少在 Oracle 1.7 中)取决于随机数,并且在两个线程同时访问它的情况下 和 获得相同的随机数(不太可能但可能),该方法将抛出 IOException
.
另一个方法将在同一个线程中调用,如果您调用它...好吧,从线程中调用。