创建线程的四种方法

Java多线程创建(不管怎样,启动线程调用start())

一.继承Thread实现多线程,

而后覆写run()[run方法为线程类核心方法]相当于主线程main(),相当于入口

a.一个线程调用两次start(),抛出状态异常。
即一个线程的start()方法只能调用一次

b.native声明的方法,没有方法体,只有声明,但本地方法不是抽象方法,
    而是Java调用C语言方法(JNI平台)
    registerNatives方法包含所有与线程相关的操作系统方法
c.run()是由JVM创建完本地操作系统线程回调后回调的方法,不手工调用(否则就是普通方法)

二.覆写Runnable接口实现多线程而后覆写run()。推荐第二个

a.覆写Runnable接口实现多线程,可以避免单继承
b.代理模式 当子类实现Runnable接口,此时子类与Thread就是典型的代理设计模式
(相当于子类负责真实业务操作,Thread资源调度、创建线程辅助真实业务)
函数式编程:
  Runnable r = () -> {
        System.out.println();
    }

对比 继承Thread类 与 实现Runnable接口 区别:

a.实现Runnable 接口可以避免多继承局限
b.Runnable实现的多线程可以更好的体现程序共享概念

三.Callable接口实现多线程(jDK1.5新增接口)

a.核心方法call()
b.有返回值
    Callable  callable = new MyThread();        // MyThread类 实现了 Callable接口
    Runnable runnable = new FutureTask(callable);   // 
    Thread thread  = new Thread(runnable);
    thread.start();

四.线程池(JDK1.5)

三大优点:

1.降低资源消耗:通过重复利用已经创建好的线程,降低线程创建与消耗带来的消耗。
2.提高响应速度:当任务到达时,不需要等待线程创建就可以立即执行。
3.提高线程的可管理性:同一进行线程分配、调度和监控

线程池四大组成部分:

1.corePool : 核心线程池
2.BoclingQueue:阻塞队列
3.MaxPool : 线程池容纳的最大线程数量

线程池流程:

a.若当前运行的线程数 < corePoolSize, 则创建新的线程执行任务,而后将此线程放入corePool(需要全局锁)
b.若当前线程数 >= corePoolSize ,则将任务放入阻塞队列等待调度执行(95%)
c.若阻塞队列已满,则试图创建新的线程来执行任务(需要全局锁)
d.若创建线程后,总线程 > MaxPoolSize, 则任务被拒绝,调度策略返回给用户

工作线程:

线程池创建线程时,将线程封装为Worker。
Worker在执行完任务后,还会循环从工作队列中取得任务来执行。

线程池ExectorService:

普通线程池ThreadPoolExector:
1.手工创建线程池

ThreadPoolExecutor tpe  = new ThreadPoolExecutor(
    int  corePoolSize,  //线程池基本大小
    int maximumPoolSize,    
    long keepAliveTime,     //任务队列
    TimeUnit unit,
    BlockingQueue<Runnable> workQueue,
    RejectedExecutionHandler hander
)

1).corePoolSize(线程池基本大小):

当提交一个任务到线程池中,线程池会创建一个线程来执行任务。
即使其他空闲的基本线程能够执行任务也会创建新线程。直到当
前线程池中线程数量 > 基本大小才不会创建。

2).BlockingQueue(任务队列):用于保存等待执行任务的阻塞队列。
a.ArrayBlockQueue :基于数组的有界限阻塞队列。按照FIFO对元素排序。

b.LinkedBolockingQueue :基于链表结构的无界限阻塞队列。吞吐量高于ArrayBlockQueue
FixedThreadPool()、singleThreadPool()都采用此队列。

c.synchronousQueue : 不存储元素的阻塞队列。每个插入操作必须等待另一个线程移除操作、否则插入操作一直处于阻塞状态。
吞吐量 > LinkedBolockingQueue
CachedThreadPool ; 采用此队列

d.PriorityBlockingQueue : 具有优先级的无界限阻塞队列

3).keepAliveTime(线程活动保持时间):
线程池工作线程空闲后,保持存活的时间

4).TimeUnit : keepAliveTime的时间单位

5).RejectedExecutionHandler(饱和策略):线程池满时无法处理新任务的执行策略。
线程池默认采用AbortPolicy(抛出异常) - 可以省略此参数

向线程池提交任务:

1)execute(Runnable run) : 
用于提交不需要返回值得任务,所以无法判断任务是否被线程池执行成功。
2)submit(Runnable Callable): Future对象
用于提交需要返回值得任务。可以通过future对象判断任务是否执行成功。
future.get() 会阻塞当前线程,直到任务全部执行完毕。

手工关闭线程池:

1)shutdown();
停止所有没有在执行任务的线程。

2)shutdownNow();
停止所有正在执行以及空闲线程。

Exector : 线程的执行机制

2.通过exector的工具类Exectors、可以取得3中类型的普通线程池

2.1 FixedThreadPool(int nThreads) :固定大小线程池
ixedThreadPool适用于为了满足资源管理需求而需要限制当前线程数量的场合,使用于负载比较重的服务器。

2.2 SigleThreadPoolExector : 单线程池
适用于需要保证顺序执行各个任务的场景

2.3 CachedThreadPool : 缓存线程池
当提交任务速度高于线程池中任务处理速度时,缓存线程池会不断创建新线程。
适用于很多的短期的异步小程序,以及负载教轻的服务器。

调度线程池ScheduleExectorService():

newScheduledThreadPool(int nThreads)
scheduleAtFixedRates(command, initiablDelay, period, unit)
command:要执行的任务
initiablDelay;任务延迟多少单元后执行
period:周期,每隔几秒执行一次
unit:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值