-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
232c04e
commit 80a8fb8
Showing
15 changed files
with
1,294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http:https://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http:https://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http:https://maven.apache.org/POM/4.0.0 http:https://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.study</groupId> | ||
<artifactId>practice</artifactId> | ||
<version>1.0-SNAPSHOT</version> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.projectlombok</groupId> | ||
<artifactId>lombok</artifactId> | ||
<version>1.16.10</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>log4j</groupId> | ||
<artifactId>log4j</artifactId> | ||
<version>1.2.17</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-log4j12</artifactId> | ||
<version>1.7.21</version> | ||
</dependency> | ||
|
||
<dependency> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
<version>1.7.21</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-lang3</artifactId> | ||
<version>3.7</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-aop</artifactId> | ||
<version>4.3.12.RELEASE</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-beans</artifactId> | ||
<version>4.3.12.RELEASE</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>org.springframework</groupId> | ||
<artifactId>spring-core</artifactId> | ||
<version>4.3.12.RELEASE</version> | ||
</dependency> | ||
<dependency> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
<version>20.0</version> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<pluginManagement> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-compiler-plugin</artifactId> | ||
<version>3.2</version> | ||
<configuration> | ||
<source>1.8</source> | ||
<target>1.8</target> | ||
<encoding>UTF-8</encoding> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</pluginManagement> | ||
</build> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.study.concurrent; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.concurrent.*; | ||
|
||
/** | ||
* | ||
* @description: Future使用 | ||
* <p> | ||
* 实现callable接口,同时重写call方法,方法submit不仅可以传入Callable对象, | ||
* 而且还可以Runnable,同时可以从api中可以看到submit(Callable<T> task) | ||
* get具有阻塞性,而isDone不阻塞 | ||
* Callable<void> | ||
* </p> | ||
* @author: lyz | ||
* @date: 2020/05/24 11:48 | ||
**/ | ||
@Slf4j | ||
public class CallableTask { | ||
|
||
static class Task implements Callable<Integer>{ | ||
|
||
@Override | ||
public Integer call() throws Exception { | ||
System.out.println("启动线程进行计算操作"); | ||
int sum = 0; | ||
for (int i= 0;i<1000;i++){ | ||
sum += i; | ||
} | ||
TimeUnit.SECONDS.sleep(3); | ||
return new Integer(sum); | ||
} | ||
} | ||
|
||
public static void main(String[] args) throws InterruptedException { | ||
ThreadPoolExecutor executor = new ThreadPoolExecutor(2,3,5L,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>()); | ||
Task task = new Task(); | ||
Future<Integer> result = executor.submit(task); | ||
executor.shutdown(); | ||
TimeUnit.SECONDS.sleep(1); | ||
System.out.println("主线程在执行任务"); | ||
try{ | ||
System.out.println("计算结果为:"+result.get()); | ||
}catch(Exception e){ | ||
log.info("任务执行异常:{}",e.getMessage()); | ||
} | ||
System.out.println("所有任务执行完毕"); | ||
} | ||
|
||
} |
78 changes: 78 additions & 0 deletions
78
src/main/java/com/study/concurrent/CompletionServiceTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
package com.study.concurrent; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Date; | ||
import java.util.List; | ||
import java.util.concurrent.*; | ||
|
||
|
||
/*** @description: CompletionSerivce使用 | ||
* <p> | ||
* 采用异步的方式一边处理新的任务,一边处理完成任务的结果 | ||
* 也就是说在处理多个任务时,可以实现先处理的任务,先拿到结果 | ||
* 采用 submit+take,不至于在一个任务没有完成的情况下,其余的结果不能处理 | ||
* 你可以将其理解成Executor+BlockingQueue的结合体,此时你可以使用其实现 | ||
* ExecutorCompletionService,进行异构并行 | ||
* </p> | ||
* @author: lyz | ||
* @date: 2020/05/24 22:02 | ||
**/ | ||
public class CompletionServiceTest { | ||
public static void main(String[] args) { | ||
Long start = System.currentTimeMillis(); | ||
//开启5个线程 | ||
ExecutorService exs = Executors.newFixedThreadPool(4); | ||
try { | ||
int taskCount = 10; | ||
// 结果集 | ||
List<Integer> list = new ArrayList<Integer>(); | ||
List<Future<Integer>> futureList = new ArrayList<Future<Integer>>(); | ||
|
||
// 1.定义CompletionService | ||
CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(exs); | ||
|
||
// 2.添加任务,需要执行的业务 | ||
for (int i = 0; i < taskCount; i++) { | ||
Future<Integer> future = completionService.submit(new Task(i + 1)); | ||
futureList.add(future); | ||
} | ||
|
||
// 3.获取结果 | ||
for (int i = 0; i < taskCount; i++) { | ||
Integer result = completionService.take().get(); | ||
System.out.println("任务i==" + result + "完成!" + new Date()); | ||
list.add(result); | ||
} | ||
|
||
System.out.println("list=" + list); | ||
} catch (Exception e) { | ||
e.printStackTrace(); | ||
} finally { | ||
//关闭线程池 | ||
exs.shutdown(); | ||
} | ||
|
||
} | ||
|
||
//实现Callable接口,重写call方法 | ||
static class Task implements Callable<Integer> { | ||
Integer i; | ||
|
||
public Task(Integer i) { | ||
super(); | ||
this.i = i; | ||
} | ||
|
||
@Override | ||
public Integer call() throws Exception { | ||
if (i == 4) { | ||
Thread.sleep(5000); | ||
} else { | ||
Thread.sleep(1000); | ||
} | ||
System.out.println("线程:" + Thread.currentThread().getName() + "任务i=" + i + ",执行完成!"); | ||
return i; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
package com.study.concurrent; | ||
|
||
import java.util.concurrent.Callable; | ||
import java.util.concurrent.ThreadPoolExecutor; | ||
import java.util.concurrent.TimeUnit; | ||
|
||
/** | ||
* | ||
* @description: Future使用 | ||
* <p> | ||
* FutureTask:是Future的实现类,而且在使用线程池时,默认的情况下也是使用 | ||
* futureTask类作为接口Future的实现类,但需要注意的是,Future接口调用get()方法 | ||
* 取得处理的结果时是阻塞性的,也就是如果调用get()方法时,任务尚未完成,则 | ||
* 调用get()方法时一直阻塞到此任务完成时为止。如果是这样的相关,则前面先执行的任务 | ||
* 一旦耗时很多,则后面的任务调用get()方法就呈现阻塞状态,也就是排队等待,大大影响运行效率。 | ||
* 也即主线程并不能保证首先获的是最先完成任务的返回值,这是future的缺点,影响效率 | ||
* </p> | ||
* @author: lyz | ||
* @date: 2020/05/24 12:00 | ||
**/ | ||
public class FutureTask { | ||
/** | ||
* FutureTask由线程池执行 | ||
*/ | ||
private static void exeForPool(){ | ||
// 创建 FutureTask,采用三个线程执行主线程 | ||
java.util.concurrent.FutureTask<Integer> futureTask = new java.util.concurrent.FutureTask<>(()-> 1+2); | ||
// 创建线程池 | ||
ThreadPoolExecutor executor = ThreadPoolBuilder.fixedPool().build(); | ||
|
||
try{ | ||
// 提交 FutureTask | ||
executor.submit(futureTask); | ||
// 获取计算结果 | ||
Integer result = futureTask.get(); | ||
System.out.println(result); | ||
}catch(Exception e){ | ||
e.printStackTrace(); | ||
}finally { | ||
//进行优雅关闭 | ||
ThreadPoolUtil.gracefulShutdown(executor,1); | ||
|
||
} | ||
} | ||
|
||
/** | ||
* FutureTask由线程处理 | ||
*/ | ||
private static void exeForThread(){ | ||
// 创建 FutureTask | ||
java.util.concurrent.FutureTask<Integer> futureTask = new java.util.concurrent.FutureTask<>(()-> 1+2); | ||
// 创建并启动线程 | ||
Thread T1 = new Thread(futureTask); | ||
T1.start(); | ||
// 获取计算结果 | ||
try{ | ||
Integer result = futureTask.get(); | ||
System.out.println(result); | ||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
} | ||
|
||
} | ||
|
||
/** | ||
* 利用FutureTask实现烧水泡茶 | ||
*/ | ||
private static void fireWater(){ | ||
|
||
// 创建任务 T2 的 FutureTask | ||
java.util.concurrent.FutureTask<String> ft2 = new java.util.concurrent.FutureTask<>(new T2Task()); | ||
// 创建任务 T1 的 FutureTask | ||
java.util.concurrent.FutureTask<String> ft1 = new java.util.concurrent.FutureTask<>(new T1Task(ft2)); | ||
// 线程 T1 执行任务 ft1 | ||
Thread t1 = new Thread(ft1); | ||
t1.start(); | ||
// 线程 T2 执行任务 ft2 | ||
Thread t2 = new Thread(ft2); | ||
t2.start(); | ||
// 等待线程 T1 执行结果 | ||
try{ | ||
System.out.println(ft1.get()); | ||
|
||
}catch (Exception e){ | ||
e.printStackTrace(); | ||
} | ||
|
||
|
||
|
||
} | ||
/** | ||
* 洗水壶、烧开水、泡茶,实现Callable接口,重写call方法 | ||
*/ | ||
static class T1Task implements Callable<String> { | ||
java.util.concurrent.FutureTask<String> ft2; | ||
T1Task(java.util.concurrent.FutureTask<String> ft2){ | ||
this.ft2 = ft2; | ||
} | ||
@Override | ||
public String call() throws Exception { | ||
System.out.println("T1: 洗水壶..."); | ||
TimeUnit.SECONDS.sleep(1); | ||
|
||
System.out.println("T1: 烧开水..."); | ||
TimeUnit.SECONDS.sleep(15); | ||
// 获取 T2 线程的茶叶 | ||
String tf = ft2.get(); | ||
System.out.println("T1: 拿到茶叶:"+tf); | ||
|
||
System.out.println("T1: 泡茶..."); | ||
return " 上茶:" + tf; | ||
} | ||
} | ||
/** | ||
* 洗茶壶、洗茶杯、拿茶叶,实现Callable接口,重写call方法 | ||
*/ | ||
static class T2Task implements Callable<String> { | ||
@Override | ||
public String call() throws Exception { | ||
System.out.println("T2: 洗茶壶..."); | ||
TimeUnit.SECONDS.sleep(1); | ||
|
||
System.out.println("T2: 洗茶杯..."); | ||
TimeUnit.SECONDS.sleep(2); | ||
|
||
System.out.println("T2: 拿茶叶..."); | ||
TimeUnit.SECONDS.sleep(1); | ||
return " 白茶 "; | ||
} | ||
} | ||
public static void main(String[] args) { | ||
exeForPool(); | ||
exeForThread(); | ||
fireWater(); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package com.study.concurrent; | ||
|
||
import lombok.extern.slf4j.Slf4j; | ||
|
||
import java.util.concurrent.*; | ||
|
||
/** | ||
* | ||
* @description: Future使用 | ||
* <p> | ||
* 实现callable接口,同时重写call方法,其优点:与Runnable不同的是,其可以返回结果, | ||
* 同时可以声明异常,返回一个执行检查的异常信息,而Runnable返回的是void, | ||
* 因此在程序上方便排查问题,同时了解执行的结果情况,如果返回的结果想是void的,则可以在实现时选择 | ||
* Callable<void> | ||
* </p> | ||
* @author: lyz | ||
* @date: 2020/05/24 11:23 | ||
**/ | ||
@Slf4j | ||
public class FutureTest { | ||
static class MyCallable implements Callable<String>{ | ||
public String call() throws Exception { | ||
//业务逻辑执行部分 | ||
log.info("do something in callable"); | ||
Thread.sleep(1000); | ||
return "Done"; | ||
} | ||
} | ||
|
||
public static void main(String[] args) throws InterruptedException, ExecutionException { | ||
//ExecutorService executorService = Executors.newCachedThreadPool(); | ||
ThreadPoolExecutor executorService = new ThreadPoolExecutor(2,3,5L,TimeUnit.SECONDS,new LinkedBlockingDeque<>()); | ||
//执行需要提交的任务 | ||
Future<String> future = executorService.submit(new MyCallable()); | ||
log.info("do something in main"); | ||
Thread.sleep(1000); | ||
//拿到执行后返回的结果 | ||
String result = future.get(); | ||
log.info("result:{}",result); | ||
executorService.shutdown(); | ||
} | ||
|
||
} |
Oops, something went wrong.