Spring 中的 @Async 和 @Scheduled 理解

来源:互联网 发布:ubuntu无法删除文件夹 编辑:程序博客网 时间:2024/06/10 13:09

@Async

spring-test.xml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd">
<task:annotation-driven scheduler="myScheduler" executor="myExecutor"/>
<task:executor id="myExecutor" pool-size="20"/>
<task:scheduler id="myScheduler" pool-size="5"/>
<bean id="hello" class="hello.world.task.TestTask" />
</beans>

spring官网例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.concurrent.Future;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class GitHubLookupService {
RestTemplate restTemplate = new RestTemplate();
@Async
public Future<User> findUser(String user) throws InterruptedException {
System.out.println("Looking up " + user);
User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return new AsyncResult<User>(results);
}
}

Async动作类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package hello.world.task;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import java.util.concurrent.Future;
/**
* Created by yang on 15-12-3.
*/
public class TestTask {
@Async
public Future<String> run() throws InterruptedException {
System.out.println(Thread.currentThread().getName());
Thread.sleep(20 * 1000);
return new AsyncResult<String>("hello");
}
}

java测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package hello.world;
import hello.world.task.TestTask;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
* Created by yang on 15-11-9.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-test.xml")
public class HelloTest {
@Autowired
private TestTask testTask;
@Test
public void run() throws ExecutionException, InterruptedException {
Future<String> hello = testTask.run();
System.out.println("after 20 s?");
String h = hello.get();
System.out.println(h);
}
}

以上,它是以myexecutor的线程池来执行的.

@Scheduled

@Async改为@Scheduled

1
2
3
4
5
6
7
public class TestTask {
@Scheduled(cron = "*/2 * * * * *")
public void run() throws InterruptedException {
System.out.println(Thread.currentThread().getName());
}
}

看执行结果,它是以myscheduler的线程池来执行的,而且返回值只能是void.

同时使用 @Scheduled 和 @Async

不过注意,如果这样子使用了,异步执行的返回结果Future就不要这样子使用了,这时返回值只能是void.

同时使用这两个注解的效果,相当于@Scheduled负责调度,而executor负责执行。

看打印的线程可知:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
myExecutor-1
myExecutor-2
myExecutor-3
myExecutor-4
myExecutor-5
myExecutor-6
myExecutor-7
myExecutor-8
myExecutor-9
myExecutor-10
myExecutor-11
myExecutor-12
myExecutor-13
myExecutor-14
myExecutor-15
myExecutor-16

它是非常有规律的:每一个任务,都是下一条线程。然后轮回。


原创粉丝点击