多线程java实现代码_Java多线程的4种实现方式

本文介绍了Java实现多线程的四种方式:继承Thread类、实现Runnable接口、实现Callable接口及使用线程池。详细讨论了线程池的工作原理,包括核心线程数、最大线程数、存活时间、阻塞队列等,并列举了Java自带线程池的几种实现,如newFixedThreadPool、newSingleThreadExecutor等,还分析了线程池的拒绝策略。
摘要由CSDN通过智能技术生成

Java有四种实现多线程的方式:

1).继承Thread类

2).实现Runnable接口

3).实现Callable接口

4).使用线程池

前三种实现方式的代码:

1 public classMultiThread {2   //继承Thread类

3 static class MyThread1 extendsThread{4 @Override5 public voidrun() {6 System.out.println(Thread.currentThread().getName()+": extends Thread方式");7 }8 }9   //实现Runnable接口

10 static class MyThread2 implementsRunnable{11 @Override12 public voidrun() {13 System.out.println(Thread.currentThread().getName()+": implements Runnable方式");14 }15 }16   //实现Callable接口

17 static class MyThread3 implements Callable{18 @Override19 public String call() throwsException {20 return Thread.currentThread().getName()+": implements Callable方式";21 }22 }23

24 public static void main(String[] args) throwsException{25 Thread thread1 = newMyThread1();26 Thread thread2 = new Thread(newMyThread2());27 FutureTask futureTask = new FutureTask<>(newMyThread3());28 Thread thread3 = newThread(futureTask);29

30 thread1.start();31 thread2.start();32 thread3.start();33 System.out.println(futureTask.get());34 }35 }

运行结果:

Thread-0: extendsThread方式

Thread-1: implementsRunnable方式

Thread-2: implements Callable方式

line26,27行当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考Thread类部分源代码:

public class Thread implements Runnable {

public Thread(Runnable target) {

init(null, target, "Thread-" + nextThreadNum(), 0);

}

@Override

public void run() {

if (target != null) {

target.run();

}

}

}

1.继承Thread本质上也是实现Runnable接口。

2.实现Callable接口的任务线程能返回执行结果,而实现Runnable接口的线程不能返回结果

3.使用Callable的方式时候需要用FutureTask<>进行包装(适配),FutureTask实现了Runnable和Future,通过future里面的get()方法来得到返回值。需要注意的是get()方法是阻塞的,就是说取不到值会使主线程一直等待。

4.生产中几乎都会使用线程池。

线程池:用来控制运行的线程的数量,处理过程中将任务放入等待队列,然后在线程创建后启动这些任务。如果线程数量超过了最大数量(maximumPoolSize),超出数量的线程将会在等待队列排队等候。如果等待队列已满,再进来的任务就会按照拒绝策略拒绝。

线程池的特点:线程复用,控制最大并发数,管理线程。

线程池的优势:

1.降低资源消耗,通过复用线程来降低创建和销毁线程的消耗。

2.提高响应速度,当任务到达时不需要等待创建线程。

3.提高线程的可管理性,使用线程池可以进行统一的分配,监控和调优。

java自带的线程池的实现:

//固定数量线程的线程池

ExecutorService threadPool1 =Executors.newFixedThreadPool(cpuNum);//一个线程的线程池

ExecutorService threadPool2 =Executors.newSingleThreadExecutor();//多个线程的线程池

ExecutorService threadPool3 =Executors.newCachedThreadPool();//Java8新特性     ExecutorService threadPool3 = Executors.newWorkStealingPool();

上面几线程池的底层都是ThreadPoolExecutor(),ThreadPoolExecutor是线程池的核心类。ThreadPoolExecutor的构造器最多有7个可配参数:

ThreadPoolExecutor的7个参数:

corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;

maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;

keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;

unit:参数keepAliveTime的时间单位,有7种取值:

TimeUnit.DAYS;//天

TimeUnit.HOURS;//小时

TimeUnit.MINUTES;//分钟

TimeUnit.SECONDS;//秒

TimeUnit.MILLISECONDS;//毫秒

TimeUnit.MICROSECONDS;//微妙

TimeUnit.NANOSECONDS;//纳秒

workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种选择:ArrayBlockingQueue和PriorityBlockingQueue使用较少,一般使用LinkedBlockingQueue和Synchronous。线程池的排队策略与BlockingQueue有关。

threadFactory:线程工厂,主要用来创建线程;

handler:表示当拒绝处理任务时的策略,有以下四种取值:

ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。

ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。

ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)

ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

线程池详细原理可以参考:https://www.cnblogs.com/dolphin0520/p/3932921.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值