Java 为什么使用和不使用ExecutorService的任务需要相同的时间?
我在SpringBoot中使用JDBC模板和executor服务具有以下项目结构。应用程序使用线程和不使用线程所花费的时间几乎相同。我预计时间至少减少三分之一 我从中阅读了以下内容,但我不知道如何在我的代码中应用: 为了能够在线程中使用事务,我们需要了解事务是如何在spring中工作的。spring中的事务信息存储在ThreadLocal变量中。因此,这些变量特定于单个线程上正在进行的事务 是我在Java 为什么使用和不使用ExecutorService的任务需要相同的时间?,java,multithreading,spring-boot,executorservice,Java,Multithreading,Spring Boot,Executorservice,我在SpringBoot中使用JDBC模板和executor服务具有以下项目结构。应用程序使用线程和不使用线程所花费的时间几乎相同。我预计时间至少减少三分之一 我从中阅读了以下内容,但我不知道如何在我的代码中应用: 为了能够在线程中使用事务,我们需要了解事务是如何在spring中工作的。spring中的事务信息存储在ThreadLocal变量中。因此,这些变量特定于单个线程上正在进行的事务 是我在SqlUtilities中长期运行的任务。executeSql(sqlName,values,dat
SqlUtilities中长期运行的任务。executeSql(sqlName,values,dataSource)
导致问题?
有人知道为什么吗?欢迎任何解决方案。
@SpringBootApplication
public class ApplicationMain implements CommandLineRunner {
@Autowired
@Qualifier(value = "mainExecutorService")
public ExecutorService mainExecutorService;
@Autowired
@Qualifier(value = "mut")
public Mut mut;
@Autowired
@Qualifier(value = "apt")
public Apt apt;
public static void main(String[] args){
SpringApplication.run(ApplicationMain.class, args);
}
@Override
public void run(String... args) throws Exception {
try {
// First thread
mainExecutorService.submit(() -> {
mut.initialise("2019", "10", "31");
apt.sum();
}, true);
// Second thread
mainExecutorService.submit(() -> {
apt.initialise("2019", "10", "31");
mut.sum();
}, true);
mainExecutorService.shutdown();
if (mainExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES))
System.out.println("done");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mainExecutorService.shutdownNow();
}
}
}
class Apt implements Som {
private String year, month, day ;
private long staringProcessingTime;
@Autowired
@Qualifier(value = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Override
public void initialize (String year, String month, String day) {
this.year = year;
this.month = month;
this.day = day;
}
@Override
public void sum() {
staringProcessingTime = System.currentTimeMillis();
System.out.println("Started Second thread. starting time is:".concat(String.valueOf(staringProcessingTime)));
deleteInsertUpdate();
}
@Override
public void deleteInsertUpdate() {
String queryDelete = "";
String queryInsert = "";
String queryUpdate = "";
try {
service.submit(() -> jdbcTemplate.update(queryDelete));
service.submit(() -> jdbcTemplate.update(queryInsert));
service.submit(() -> jdbcTemplate.update(queryUpdate));
service.shutdown();
if (service.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES))
execute();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
service.shutdownNow();
}
}
@Override
public void execute() {
// long running task here ....
if( SqlUtilities.executeSql(sqlName, values, dataSource) )
print();
}
@Override
public void print() {
long endProcessingTime = System.currentTimeMillis();
System.out.println("Ended second thread. total time in millisecond:".concat(String.valueOf(endProcessingTime - staringProcessingTime)));
}
}
配置
@Configuration
class ExecutorservicConfig {
@Bean("mainExecutorService")
public ExecutorService mainExecutorService() {
return Executors.newFixedThreadPool(2);
}
@Bean(name = "apt")
public Apt createApt(){
return new Apt();
}
@Bean(name = "mut")
public Mut createMut(){
return new Mut();
}
}
接口
interface Som {
ExecutorService service = Executors.newCachedThreadPool();
void initialize (String year, String month, String day);
void sum();
void deleteInsertUpdate();
void execute();
void print();
}
第一个类考虑在第一个线程中执行
class Mut implements Som {
private String year, month, day ;
@Autowired
@Qualifier(value = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
private long staringProcessingTime;
@Override
public void initialize (String year, String month, String day) {
this.year = year;
this.month = month;
this.day = day;
}
@Override
public void sum() {
staringProcessingTime = System.currentTimeMillis();
System.out.println("Started first thread. starting time is:".concat(String.valueOf(staringProcessingTime)));
deleteInsertUpdate();
}
@Override
public void deleteInsertUpdate() {
String queryDelete = "";
String queryInsert = "";
String queryUpdate = "";
try {
service.submit(() -> jdbcTemplate.update(queryDelete));
service.submit(() -> jdbcTemplate.update(queryInsert));
service.submit(() -> jdbcTemplate.update(queryUpdate));
service.shutdown();
if (service.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES))
execute();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
service.shutdownNow();
}
}
@Override
public void execute() {
// long running task here ....
if( SqlUtilities.executeSql(sqlName, values, dataSource) )
print();
}
@Override
public void print() {
long endProcessingTime = System.currentTimeMillis();
System.out.println("Ended first thread. total time in millisecond:".concat(String.valueOf(endProcessingTime - staringProcessingTime)));
}
}
第二个类考虑在第二个线程中执行。
@SpringBootApplication
public class ApplicationMain implements CommandLineRunner {
@Autowired
@Qualifier(value = "mainExecutorService")
public ExecutorService mainExecutorService;
@Autowired
@Qualifier(value = "mut")
public Mut mut;
@Autowired
@Qualifier(value = "apt")
public Apt apt;
public static void main(String[] args){
SpringApplication.run(ApplicationMain.class, args);
}
@Override
public void run(String... args) throws Exception {
try {
// First thread
mainExecutorService.submit(() -> {
mut.initialise("2019", "10", "31");
apt.sum();
}, true);
// Second thread
mainExecutorService.submit(() -> {
apt.initialise("2019", "10", "31");
mut.sum();
}, true);
mainExecutorService.shutdown();
if (mainExecutorService.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES))
System.out.println("done");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
mainExecutorService.shutdownNow();
}
}
}
class Apt implements Som {
private String year, month, day ;
private long staringProcessingTime;
@Autowired
@Qualifier(value = "jdbcTemplate")
private JdbcTemplate jdbcTemplate;
@Override
public void initialize (String year, String month, String day) {
this.year = year;
this.month = month;
this.day = day;
}
@Override
public void sum() {
staringProcessingTime = System.currentTimeMillis();
System.out.println("Started Second thread. starting time is:".concat(String.valueOf(staringProcessingTime)));
deleteInsertUpdate();
}
@Override
public void deleteInsertUpdate() {
String queryDelete = "";
String queryInsert = "";
String queryUpdate = "";
try {
service.submit(() -> jdbcTemplate.update(queryDelete));
service.submit(() -> jdbcTemplate.update(queryInsert));
service.submit(() -> jdbcTemplate.update(queryUpdate));
service.shutdown();
if (service.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES))
execute();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
service.shutdownNow();
}
}
@Override
public void execute() {
// long running task here ....
if( SqlUtilities.executeSql(sqlName, values, dataSource) )
print();
}
@Override
public void print() {
long endProcessingTime = System.currentTimeMillis();
System.out.println("Ended second thread. total time in millisecond:".concat(String.valueOf(endProcessingTime - staringProcessingTime)));
}
}
实用程序类
class SqlUtilities {
public static boolean executeSql(String sqlName, Map<String,String> values, DataSource dataSource){
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
boolean executed = false;
try{
Resource[] resources = resolver.getResources("classpath*:sql/*.sql");
for(Resource resource: resources)
{
if(sqlName.equals(resource.getFilename()))
{
File tempFile = File.createTempFile(resource.getFilename(), ".sql");
Path tempPath = Paths.get(tempFile.getAbsolutePath());
try (InputStream inputStream = resource.getInputStream()) {
FileUtils.copyInputStreamToFile(inputStream, tempFile);
String contents = new String(Files.readAllBytes(tempPath));
String newContents = StringSubstitutor.replace(contents, values);
Files.write(tempPath, Collections.singleton(newContents), StandardOpenOption.TRUNCATE_EXISTING);
Resource tempResource = new FileUrlResource(tempPath.toString());
ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(tempResource);
databasePopulator.execute(dataSource);
} finally {
executed = Files.deleteIfExists(tempPath);
}
}
}
}catch (Exception e){
System.out.println(e.getMessage());;
}
return executed;
}
类SqlUtilities{
公共静态布尔执行SQL(字符串sqlName、映射值、数据源数据源){
ResourcePatternResolver解析器=新路径匹配ResourcePatternResolver();
布尔值=假;
试一试{
Resource[]resources=resolver.getResources(“classpath*:sql/*.sql”);
for(资源:资源)
{
if(sqlName.equals(resource.getFilename()))
{
File tempFile=File.createTempFile(resource.getFilename(),“.sql”);
Path tempPath=Path.get(tempFile.getAbsolutePath());
try(InputStream InputStream=resource.getInputStream()){
copyInputStreamToFile(inputStream,tempFile);
字符串内容=新字符串(Files.readAllBytes(tempPath));
String newContents=StringSubstitutor.replace(内容、值);
write(tempPath、Collections.singleton(newContents)、StandardOpenOption.TRUNCATE_EXISTING);
Resource tempResource=new FileUrlResource(tempPath.toString());
ResourceDatabasePopulator databasePopulator=新的ResourceDatabasePopulator(tempResource);
databasePopulator.execute(数据源);
}最后{
executed=Files.deleteIfExists(tempPath);
}
}
}
}捕获(例外e){
System.out.println(e.getMessage());;
}
已执行的返回;
}
此代码不会运行。@Autowired
在静态
字段上不起作用。它们做的工作量相同,为什么一个比另一个快?如果有疑问,请使用探查器查看您的程序在哪里花费了大部分时间。您对@Autowired的看法是正确的,这只是为了演示。谢谢。此项目最初没有线程,花费的时间几乎与我使用线程时相同。这就是为什么我想知道为什么会发生这种情况。@rkosegi我从未使用过探查器,你能推荐一些好的探查器吗?任务是否在不同的线程中运行?尝试记录。任务是否直接或间接涉及同步可能导致它们按顺序运行的同步化?