多线程使用的一些例子
一、例子1:
package com.csii.test.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 使用多线程查找每个学生对应老师的名字。
* 使用线程池执行,增加并发,增加总体执行速度。
* 最后等全部查询完毕后,打印查询时间
*/
public class TestMultiThread {
/**
* n = 核心数*2 + 1
*/
private static ExecutorService pool = Executors.newFixedThreadPool(5);
public static void main(String[] args) {
//findMethod1();
findMethod2();
pool.shutdown();
}
/**
* 方法1:
* 模拟,使用多线程,找到每个学生的老师名字,并且打印出来。
* 使用countDownLatch
*/
private static void findMethod1() {
long begin = System.currentTimeMillis();
List<String> studentList = new ArrayList<>();
studentList.add("zhangsan");
studentList.add("lisi");
studentList.add("wangwu");
try {
CountDownLatch latch = new CountDownLatch(studentList.size());
for(String student : studentList){
pool.execute(() -> {
findTeacher(student);
latch.countDown();
});
}
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("findMethod1执行完毕,耗时:" + (System.currentTimeMillis() - begin) + "ms");
}
/**
* 方法2:使用CompletableFuture来完成
*/
private static void findMethod2() {
long begin = System.currentTimeMillis();
List<String> studentList = new ArrayList<>();
studentList.add("zhangsan");
studentList.add("lisi");
studentList.add("wangwu");
CompletableFuture.allOf(studentList.stream().map(s -> CompletableFuture.runAsync(() -> findTeacher(s))).toArray(CompletableFuture[]::new)).join();
System.out.println("findMethod2执行完毕,耗时:" + (System.currentTimeMillis() - begin) + "ms");
}
/**
* 模拟数据库中查找学生的操作,耗时3秒
*/
private static void findTeacher(String studentName) {
System.out.println("开始处理学生:" + studentName);
//模拟查数据库...等操作,查找学生的老师
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("teacher: " + studentName + "'s teacher");
}
}
console:
方法1执行:
开始处理学生:zhangsan
开始处理学生:wangwu
开始处理学生:lisi
teacher: lisi's teacher
teacher: wangwu's teacher
teacher: zhangsan's teacher
findMethod1执行完毕,耗时:3043ms
方法2执行:
开始处理学生:zhangsan
开始处理学生:wangwu
开始处理学生:lisi
teacher: wangwu's teacher
teacher: zhangsan's teacher
teacher: lisi's teacher
findMethod2执行完毕,耗时:3056ms
二、例子2:
package com.csii.test.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestMultiThread2 {
private static int minProcessCnt = 1;
private static int poolSize = 5;
private static ExecutorService pool = Executors.newFixedThreadPool(poolSize);
/**
* 1.模拟,使用多线程,找到每个学生的老师名字,并且打印出来。
* @param args
*/
public static void main(String[] args) {
long begin = System.currentTimeMillis();
List<String> studentList = new ArrayList<>();
studentList.add("zhangsan");
studentList.add("lisi");
studentList.add("wangwu");
int perCnt = studentList.size() / poolSize; //每个线程处理的数量
int step = Math.max(perCnt, minProcessCnt); //每个线程处理的数量,按照step切割list
int latchNum = (studentList.size() + step - 1) / step; //处理次数 (和分页计算方法一样:pageCount = (totalCount + pageSize - 1)/pageSize )
CountDownLatch latch = new CountDownLatch(latchNum);
//切割studentList,分批查询
try {
for (int i = 0, start = 0; i < latchNum; i++) {
if(i == latchNum - 1){
doFindTeacher(studentList.subList(start, studentList.size()), latch);
}else{
doFindTeacher(studentList.subList(start, start+step), latch);
start = start + step;
}
}
//上面的切割方法,也可以这么写,更加简洁:
for (int j = 0; j < studentList.size(); j += step) {
doFindTeacher(studentList.subList(j, Math.min(j + step, studentList.size())), latch);
}
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("执行完成,耗时:" + (System.currentTimeMillis() - begin) + "ms");
pool.shutdown();
}
private static void doFindTeacher(List<String> studentList, CountDownLatch latch){
pool.execute(() -> {
try{
for(String student : studentList){
System.out.println("开始处理学生:" + student);
//模拟查数据库...等操作,查找学生的老师
Thread.sleep(3000);
System.out.println("teacher: " + student + "'s teacher");
}
}catch (Exception e){
e.printStackTrace();
}finally {
latch.countDown();
}
});
}
}
记住经典写法:
//上面的切割方法,也可以这么写,更加简洁:
for (int j = 0; j < studentList.size(); j += step) {
doFindTeacher(studentList.subList(j, Math.min(j + step, studentList.size())), latch);
}
console:
开始处理学生:wangwu
开始处理学生:zhangsan
开始处理学生:lisi
teacher: zhangsan's teacher
teacher: wangwu's teacher
teacher: lisi's teacher
执行完成,耗时:3094ms
三、例子3:
1 package com.cy.test.thread; 2 3 4 import java.util.ArrayList; 5 import java.util.List; 6 import java.util.concurrent.ExecutorService; 7 import java.util.concurrent.Executors; 8 import java.util.concurrent.FutureTask; 9 10 public class TestMultiThread3 { 11 private static int minProcessCnt = 1; 12 private static int poolSize = 5; 13 private static ExecutorService pool = Executors.newFixedThreadPool(poolSize); 14 15 /** 16 * 1.模拟,使用多线程,找到每个学生的老师名字 17 * 2.将老师们的名字返回,并且输出 18 * @param args 19 */ 20 public static void main(String[] args) { 21 long begin = System.currentTimeMillis(); 22 23 List<String> studentList = new ArrayList<>(); 24 studentList.add("zhangsan"); 25 studentList.add("lisi"); 26 studentList.add("wangwu"); 27 28 int size = studentList.size(); 29 int perCnt = size / poolSize; 30 int step = Math.max(perCnt, minProcessCnt); 31 int pollCount = (size + step - 1) / step; // 列表循环次数 32 33 List<FutureTask<List<String>>> taskList = new ArrayList<>(); 34 for (int i = 0; i < pollCount; i++) { 35 final int start = step * i; 36 final int end = (i == pollCount - 1) ? size : step * (i + 1); 37 FutureTask<List<String>> task = new FutureTask<>(() -> { 38 return doFindTeacher(studentList, start, end); 39 }); 40 taskList.add(task); 41 pool.execute(task); 42 } 43 44 //拿到返回结果 45 List<String> teacherList = new ArrayList<>(); 46 try { 47 for (FutureTask<List<String>> futureTask : taskList) { 48 List<String> list = futureTask.get(); 49 teacherList.addAll(list); 50 } 51 }catch (Exception e){ 52 e.printStackTrace(); 53 } 54 55 System.out.println(teacherList); 56 57 System.out.println("TestMultiThread3 执行完成,耗时:" + (System.currentTimeMillis() - begin) + "ms"); 58 pool.shutdown(); 59 } 60 61 62 private static List<String> doFindTeacher(List<String> studentList, int start, int end) throws InterruptedException { 63 List<String> teacherList = new ArrayList<>(); 64 for(int j=start; j<end; j++){ 65 String student = studentList.get(j); 66 System.out.println("开始处理学生:" + student); 67 68 //模拟查数据库...等操作,查找学生的老师 69 Thread.sleep(3000); 70 String teacher = student + "'s teacher"; 71 teacherList.add(teacher); 72 } 73 return teacherList; 74 } 75 }
console:
1 开始处理学生:zhangsan 2 开始处理学生:wangwu 3 开始处理学生:lisi 4 [zhangsan's teacher, lisi's teacher, wangwu's teacher] 5 TestMultiThread3 执行完成,耗时:3080ms
浙公网安备 33010602011771号