java低层源码_Java线程池及其底层源码实现分析

*/

Callable接口 && Runnable接口

callable调用call方法

runnable调用run方法

都可以被线程调用,但callable的call方法具有返回值(泛型)

Executors类(操作Executor的工具类)

ExecutorService service = Executors.newFixedThreadPool(5);//创建5个线程的线程池

ThreadPool线程池类(装着线程的容器)

线程池创建的固定线程,线程任务执行完后线程不会消失,处于等待任务的状态(idel)。

线程任务大于线程池容量时,多出来的任务放在等待队列中(内部使用BlockingQueue实现)

public class TestThreadPool{

2

public static void main(String[] args){

3

ExecutorService service = Executors.newFixedThreadPool(5);//1.创建5个线程的线程池容器

4

5

for(int i=0;i<6;i++){//2.放6个任务,线程池一次只能放5个,所以第6个任务需要重复使用旧的线程

6

service.execute(() -> {

7

System.out.println(Thread.getCurrentThread().getName());//3.打印出当前线程名

8

});

9

}

10

service.shutdown();//执行完当前任务则关闭线程

11

service.shutdownNow();//无论是否执行完都关闭线程

12

}

13

}

Future接口(线程未来产生的返回值)

public class TestFuture{

2

public static void main(String[] args){

3

//FutureTask实现类Runnable和Future接口

4

FutureTask task = new FutureTask<>(

5

Thread.sleep(500);//阻塞等待500毫秒

6

return 1000;

7

);

8

9

//new的方式启动线程任务

10

new Thread(task).start();

11

System.out.println(task.get());//阻塞等待500毫秒后得到返回值

12

///

13

ExecutorService service = Executors.newFixedThreadPool(5);//创建5个线程的线程池

14

Future future = service.submit(()->{//相当于运行类callable接口的call方法,返回1

15

Thread.sleep(500);

16

return 1;

17

});

18

System.out.println(future.get());//阻塞等待500毫秒后得到返回值

19

}

20

}

WorkStealingPool偷任务线程池

底层采用ForkJoinPool实现(开启的是Deamon守护线程,主线程退出则线程退出)

public class WorkStealingPoolTest {

2

public static void main(String[] args) throws IOException {

3

//根据CPU核数启动相应个数的线程(4核cpu---4个线程)

4

ExecutorService service = Executors.newWorkStealingPool();

5

System.out.println(Runtime.getRuntime().availableProcessors());

6

7

service.execute(new R(1000));//线程1执行任务1----1秒

8

service.execute(new R(2000));//线程2执行任务2----2秒

9

service.execute(new R(2000));//线程3执行任务3----2秒

10

service.execute(new R(2000));//线程4执行任务4----2秒

11

service.execute(new R(2000));//任务5阻塞,当线程1执行完后把任务5偷过来执行

12

13

//由于产生的是守护线程,主线程不阻塞的话,看不到输出

14

System.in.read();//将主线程阻塞

15

}

16

17

static class R implements Runnable {

18

19

int time;

20

21

R(int t) {

22

this.time = t;

23

}

24

25

@Override

26

public void run() {

27

28

try {

29

TimeUnit.MILLISECONDS.sleep(time);

30

} catch (InterruptedException e) {

31

e.printStackTrace();

32

}

33

//打印线程名---ForkJoinPool

34

System.out.println(time + " " + Thread.currentThread().getName());

35

36

}

37

38

}

39

}

ForkJoinPool(分支合并线程池)

思想:分治,把大任务拆分成小任务并行计算,计算完成后将结果合并

守护线程

public class ForkJoinPoolTest{

2

3

public static void main(String[] args) throws Exception {

4

ForkJoinPool pool = new ForkJoinPool();

5

MyTask task = new MyTask(inits, 0, inits.;ength-1);

6

ForkJoinTask taskResult = pool.submit(task);

7

try {

8

taskResult.get();//阻塞等待所有线程结果计算完成

9

} catch (InterruptedException | ExecutionException e) {

10

e.printStackTrace(System.out);

11

}

12

}

13

14

/**

15

* 单个排序的子任务

16

*/

17

static class MyTask extends RecursiveTask {

18

19

private int[] source;

20

private int start;

21

private int end;

22

23

public MyTask(int[] source,int start, int end ) {

24

this.source = source;

25

this.start = start;

26

this.end = end;

27

}

28

29

30

@Override

31

protected int[] compute() {

32

//长度小于50,进行计算

33

if(source.length <= 50) {

34

long sum = 0L;

35

for(int i=start; i

36

return sum;

37

}

38

//长度大于50,继续划分子任务

39

int middle = start + (end-start)/2;

40

41

AddTask subTask1 = new MyTask(source,start,middle);

42

AddTask subTask2 = new MyTask(source,middle,end);

43

subTask1.fork();//递归创建子任务线程

44

subTask2.fork();

45

46

//计算完成后将两个子任务的结果合并

47

return subTask1.join() + subTask2.join();

48

}

49

}

50

}

各种线程池的底层实现:

一、基本线程池:

FixedThreadPool

CachedThreadPool

ScheduledThreadPool

SingleThreadPool

二、底层创建线程池都是使用ThreadPoolExecutor类实现的,而放置任务、执行任务使用了生产者消费者模型(阻塞队列的方式)

三、源码分析

ThreadPoolExecutor的API:

ThreadPoolExecutor(int corePoolSize,//核心线程数(最小)

int maximumPoolSize,//最大线程数

long keepAliveTime, //线程运行时间

TimeUnit unit, //时间单位

BlockingQueue workQueue)//底层采用哪种阻塞队列来放线程任务

各种线程池的底层实现:

//FixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads){

return new ThreadPoolExecutor(nThreads,//初始线程数自定义

nThreads,//最大线程数自定义

0L, TimeUnit.SECONDS,//一旦启动线程池,线程永远不消失

new LinkedBlockingQueue());//链表阻塞队列

}

//CachedThreadPool(采用同步阻塞队列装任务,队列中有任务则启动新线程执行,没任务就阻塞)

public static ExecutorService newCachedThreadPool(){

return new ThreadPoolExecutor(0,//初始为0个线程

Integer.MAX_VALUE,//可以启动无限多线程

60L, TimeUnit.SECONDS,//60秒空闲则结束

new SynchronousQueue());//同步阻塞队列,有任务马上开新线程执行(容量用于为0)

}

//SingleThreadPool

return new ThreadPoolExecutor(1,//初始线程数为1

1,//最大线程数为1

0L, TimeUnit.SECONDS,//一旦启动线程池,线程永远不消失

new LinkedBlockingQueue());//链表阻塞队列

}

//ScheduledThreadPool

public newScheduledThreadPool(int corePoolSize){

super(corePoolSize,//初始线程数自定义

Integer.MAX_VALUE,//无限多线程数

0, NANOSECONDS,//一旦启动线程池,线程永远不消失

new DelayedWorkQueue());//延时阻塞队列,隔一段时间执行一次任务

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值