线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。
多线程:多个线程并行执行任务
最大优点:最大限度的利用CPU的空闲时间来处理其他任务,提高效率
多线程应用场景一:
一接口内部同时调用3个甚至更多的接口方法,正常情况下一个方法调用这些接口是同步执行的,所用的时间是所有调用方法时间的总和。这样接口调用时间会很长,会影响客户体验;在高并发的情况下会严重影响性能,甚至拖垮服务器。所以我们可以把多个接口通过多线程的方式执行,大大提高执行效率;即一个或者多个线程在执行之前必须依赖于某些必要的前提业务先执行的场景
代码实现:
package fills.thread;
import java.util.Random;
import java.util.concurrent.*;
public class ThreadUtil {
/**
* 定义要执行的任务A
* @throws Exception
*/
public void threadA() throws Exception{
Random random = new Random();
int time = random.nextInt(1000);
Thread.sleep(time);
System.out.println("A"+time);
}
/**
* 定义要执行的任务B
* @throws Exception
*/
public void threadB() throws Exception{
Random random = new Random();
int time = random.nextInt(1000);
Thread.sleep(time);
System.out.println("B"+time);
}
/**
* 定义要执行的任务C
* @throws Exception
*/
public void threadC() throws Exception{
Random random = new Random();
int time = random.nextInt(1000);
Thread.sleep(time);
System.out.println("C"+time);
}
public static void main(String[] args) throws Exception{
ThreadUtil util = new ThreadUtil();
long s = System.currentTimeMillis();
util.threadA();
util.threadB();
util.threadC();
System.out.println("同步执行时间"+(System.currentTimeMillis()-s)+"ms");
s= System.currentTimeMillis();
util.executorService(util);
System.out.println("自定义CAS执行时间"+(System.currentTimeMillis()-s)+"ms");
s= System.currentTimeMillis();
util.treadPoolExecutor(util);
System.out.println("当前线程活跃数CAS执行时间"+(System.currentTimeMillis()-s)+"ms");
s= System.currentTimeMillis();
util.countDownLatch(util);
System.out.println("countDownLatch阻塞线程执行时间"+(System.currentTimeMillis()-s)+"ms");
}
/**
* 通过Executors创建线程池实现
* @param util
*/
public void executorService(ThreadUtil util){
ExecutorService pool = Executors.newFixedThreadPool(3);
ThreadEntiry threadEntiry = new ThreadEntiry();
pool.execute(new ThreadTest("A",threadEntiry,util));
pool.execute(new ThreadTest("B",threadEntiry,util));
pool.execute(new ThreadTest("C",threadEntiry,util));
//可以根据自定义期望值自实现CAS自旋
while(!threadEntiry.isThreadA()||!threadEntiry.isThreadB()||!threadEntiry.isThreadC()){
}
System.out.println(threadEntiry.isThreadA()+" "+threadEntiry.isThreadB()+" "+threadEntiry.isThreadC());
pool.shutdown();
}
/**
* ThreadPoolExecutor 可以自建线城池
* @param util
*/
public void treadPoolExecutor(ThreadUtil util){
ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
ThreadEntiry threadEntiry = new ThreadEntiry();
pool.execute(new ThreadTest("A",threadEntiry,util));
pool.execute(new ThreadTest("B",threadEntiry,util));
pool.execute(new ThreadTest("C",threadEntiry,util));
//可以根据线程当前活跃数CAS自旋
while(pool.getActiveCount()!=0){
}
System.out.println(threadEntiry.isThreadA()+" "+threadEntiry.isThreadB()+" "+threadEntiry.isThreadC());
pool.shutdown();
}
/**
* 根据countDownLatch线程阻塞实现
* @param util
*/
public void countDownLatch(ThreadUtil util){
ThreadPoolExecutor pool = new ThreadPoolExecutor(3, 10,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
final CountDownLatch latch = new CountDownLatch(3); //设置当前线程池可并行执行的数量
ThreadEntiry threadEntiry = new ThreadEntiry();
pool.execute(new ThreadTest("A",threadEntiry,util,latch));
pool.execute(new ThreadTest("B",threadEntiry,util,latch));
pool.execute(new ThreadTest("C",threadEntiry,util,latch));
try {
latch.await();
} catch (InterruptedException e) {
} finally {
System.out.println(threadEntiry.isThreadA()+" "+threadEntiry.isThreadB()+" "+threadEntiry.isThreadC());
pool.shutdown();
}
}
//线程测试类
class ThreadTest implements Runnable{
private String type;
private ThreadEntiry threadEntiry;
private ThreadUtil util;
private CountDownLatch latch;
public ThreadTest(String type,ThreadEntiry threadEntiry,ThreadUtil util) {
this.type = type;
this.threadEntiry = threadEntiry;
this.util = util;
}
public ThreadTest(String type,ThreadEntiry threadEntiry,ThreadUtil util,CountDownLatch latch) {
this.type = type;
this.threadEntiry = threadEntiry;
this.util = util;
this.latch = latch;
}
public void run() {
try {
//该实现逻辑可根据自己业务实现不同的接口
if ("A".equals(type)) {
util.threadA();
threadEntiry.setThreadA(true);
} else if ("B".equals(type)) {
util.threadB();
threadEntiry.setThreadB(true);
} else {
util.threadC();
threadEntiry.setThreadC(true);
}
}catch (Exception e){
}finally {
if(latch!=null){
latch.countDown();
}
}
}
}
class ThreadEntiry {
//volatile修饰,变量内存共享
volatile boolean threadA;
volatile boolean threadB;
volatile boolean threadC;
public boolean isThreadA() {
return threadA;
}
public void setThreadA(boolean threadA) {
this.threadA = threadA;
}
public boolean isThreadB() {
return threadB;
}
public void setThreadB(boolean threadB) {
this.threadB = threadB;
}
public boolean isThreadC() {
return threadC;
}
public void setThreadC(boolean threadC) {
this.threadC = threadC;
}
}
}
代码运行结果
总结:分析业务接口合并使用多线程执行大大提高了效率,接口处理时间约等于最长线程执行时间