多线程
Java多线程创建方式
- 继承Thread类
- 实现Runnable接口
- 实现Callable接口
- 通过线程池获取线程对象,实现多线程
Java线程的基本状态
新建状态
使用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处在就绪状态。
他一直保持这个状态,直到程序 start() 这个线程。
就绪状态
当线程对象调用了start() 方法之后,该线程就进入到就绪状态。
就绪状态的线程处于就绪队列中,要等JVM里面线程调度器的调用。
运行状态
如果就绪状态的线程获取到CPU的资源,就可以执行 run() ,此时线程处于运行状态。
阻塞状态
如果一个线程执行了 sleep() 、suspend() 等方法,失去所占用的资源之后,该线程就从运行状态进入到阻塞状态。睡眠时间到了或者获得CPU资源后可以重新进入到就绪状态。
注意:sleep()方法是不会失去资源的,时间到了之后进行运行状态。但是被挂起或者等待方法就会失去资源。
死亡状态
运行状态的线程或者被其他终止条件终止了的线程就切换到终止状态。terminated 执行完成。
多线程中常用方法和含义
-
start():开启线程,使线程从新建状态进入到就绪状态
-
sleep():线程睡眠,令当前执行该方法的线程进入到阻塞状态,不释放CPU资源
-
wait():当前线程进入等待状态,让出CPU给其他线程,自己进入到等待队列,等待被唤醒。释放CPU资源
-
notify():唤醒一个等待队列中的线程,唤醒后会重新进入就绪状态,准备抢夺CPU资源
-
notifyAll():唤醒所有等待队列中的线程,重新进入就绪状态,准备抢夺CPU资源
-
yield():让出CPU,然后重新回到就绪状态准备再次抢夺CPU资源
-
join():加入线程,会将调用的线程加入当前线程,等待加入的线程执行完成后才会继续执行当前线程
Java多线程线程池以及核心参数
ThreadPollExecutor(): 是最原始的线程池创建方式。
**newStringThreadExecutor():**他的特点在于工作中线程数目被限制为1,操作一个无界的工作队列,所以它保证了所有任务都是被按照顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免改变线程数目
**newCachedThreadPool():**踏实一种用来处理大象段时间工作任务的线程池,具有几个特点:
- 他会试图缓存线程并重用,当没有缓存线程可以用的时候,会创建新的线程;
- 如果有线程闲置时间超过60秒的时候就会被终止并且移除缓存。
- 长时间闲置的时候,这种线程池也不会消耗什么资源。
- 他的内部使用的是SynchronousQueue作为工作队列
**newFixedThreadPool(int nThreads)😗*重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有nThreads个工作线程是活动的。也就等于任务活动超过了活动队列的数目,将在工作队列中等待空闲线程出现。如果有工作线程退出,将会有新的工作线程被创建,以弥补指定nThreads的数目。
**newSingleThreadScheduledExecutor():**创建单线程池,返回ScheduledExecutorService,可以进行定时或者周期性的工作调度。
**newScheduledThreadPool(int corePoolSize):**和newSingleThreadScheduledExecutor()类似,创建的是个ScheduledExecutorService,可以定时或者周期的工作调度,区别在于他是多个工作线程。
**newWorkStealingPool(int parallelism):**这是一个经常被人忽略的线程池,Java8中才加入这个创建方法,他的内部会构建ForkJonPool,利用Work-Stealing 算法,并行的处理任务,不保证处理顺序:
核心参数: - corePoolSize:线程池的核心线程数
- maximumPoolSize:线程池最大线程数
- keepAliveTime:空闲线程的存活时间
- unit:空闲线程存活时间单位
- workQueue:线程池等待队列
- threadFactory:线程工厂,生产线程的类
- handler:线程池拒绝策略。当线程池满的时候,该怎么拒绝后来的线程。
Java多线程中Synchronized & volatile
Synchronized: java同步锁,能够保证同一时刻只有最多只有一个线程在执行{}内的代码,达到并发安全的效果。
通过synchronized关键字来实现,所有加上synchronized和快语句,在多线程访问的时候,同一时刻只有一个线程能够使用synchronized修饰的方法或者代码块。
synchronized锁 底层实现是它的指针执行一个monitor对象的起始位置每个对象实例都会有一个monitor。其中monitor可以与对象一起创建、销毁,当多线程同时访问一段代码的时候,会先存放到EntryList集合中,接下来当线程获取到对象的monitor时,会把owner变量设置为当前线程。同时count变量+1,来保证在访问的时候只有一个引用,释放锁的时候count-1。
**volatile:**底层也是使用在被修饰的属性前面加上lock关键字。每当变量被修改时,都会优先来更新被修饰的关键字。
线程池的拒绝策略和饱和策略
当请求任务不断过来,系统又处理不过来的时候,我们需要采取的策略是拒绝服务。四种处理策略:
- AbortPolicy(抛出一个异常,默认的)终止
- DiscardPolicy(新提交的任务直接被抛弃)
- 抛弃DiscardOldestPolicy(丢弃队列中最老的任务,将当前任务继续提交给线程池)抛弃最旧
- CallerRunsPolicy(交给线程池调用所在的线程进行处理,即将某些任务退回到调用者)调用者运行
328

被折叠的 条评论
为什么被折叠?



