java线程基础及线程池

第一部分 线程基础

1. 概念简介

进程:指运行中的程序,如启动QQ、微信都是启动一个进程。

线程:由进程创建,是进程的一个实体。

一个进程可以有多个线程,一个线程中也可以创建另一个线程。

单线程:同一时刻,只允许执行一个线程。

多线程:同一时刻,可以执行多个线程。如一个迅雷进程,可以同时下载多个文件。

并发:由单核CPU实现的多任务同时执行,就是并发。

并行:由多核CPU同时执行多个任务,就是并行。

2. 创建线程的方式

2.1 继承Thread类,重写run方法
package com.javabasic.thread;

/**
 * @Description 继承Thread类,创建线程
 * @Author yuhuofei
 * @Date 2021/8/4
 */
public class ThreadTest{

    public static void main(String[] args) {
        //新建一个MyThread类的对象,当做一个线程
        MyThread myThread = new MyThread();
        //启动线程
        myThread.start();
    }
}

class MyThread extends Thread {
    //重写run方法
    @Override
    public void run() {
        System.out.println("启动一个新建的线程");
    }
}

2.2 实现Runnable接口,重写run方法
package com.javabasic.thread;

/**
 * @Description 通过实现Runnable接口,新建一个线程
 * @Author yuhuofei
 * @Date 2021/8/4
 */
public class Test {

    public static void main(String[] args) {
    
        ThreadImplRunnable threadImplRunnable = new ThreadImplRunnable();
       
        Thread thread = new Thread(threadImplRunnable);
       
        thread.start();
    }
}

class ThreadImplRunnable implements Runnable{
   
    @Override
    public void run() {
    
        System.out.println("通过实现Runnable接口,新建的一个线程");
    }
}

3.线程常用方法

  • setName()——设置线程名称
  • getName()——获取线程名称
  • start()——启动一个线程
  • run()——调用线程对象的run方法
  • setPriority()——更改线程的优先级
  • getPriority()——获取线程的优先级
  • sleep()——使当前的线程休眠一定的时间,停止执行,但不会释放锁
  • interrupt()——中断线程。一般用于中断正在休眠的线程,使之唤醒
  • yield()——线程的礼让。让出CPU,让其它线程执行,但不会释放本线程持有的锁
  • join()——线程的插队。抢占执行顺序。

4. 线程的生命周期

线程的6种状态
从官方的介绍来看,线程的生命周期主要包含六种状态:

  • new:新建状态
  • runnable:可运行态
  • timed_waiting:超时等待状态
  • waiting:等待状态
  • blocked:阻塞状态
  • teminated:终止状态

其中runnable状态,又可细分为ready(就绪)和running(运行)状态,因此如果要细分起来,线程的生命周期应该有七种状态。

线程调用sleep()方法,会使得线程进行timedwaiting超时等待状态,休眠一段时间,这个过程中,线程不会释放锁,直到休眠时间结束,重新进入runnable状态。

线程调用wait()方法,线程进入waiting(等待)状态,这个过程中,会释放锁,直到其它线程通过调用notify()或者是notifyAll()方法将其唤醒。

线程调用同步方法或同步代码块时,遇到锁,在没有获取到锁时,会进入blocked阻塞状态,直到获得锁,才重新进入runnable状态。



第二部分 线程池

1. ThreadPoolExecutor类

ThreadPoolExecutor类是线程池的核心类,它提供了4个构造方法,分别如下:

  • 第1个构造方法,包含5个参数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), defaultHandler);
}
  • 第2个构造方法,包含6个参数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         threadFactory, defaultHandler);
}
  • 第3个构造方法,包含6个参数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          RejectedExecutionHandler handler) {
    this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
         Executors.defaultThreadFactory(), handler);
}
  • 第4个构造方法,包含7个参数
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

通过观察可以看出,前面的3个构造方法都是在第4个的基础之上演变得到的,所以只要弄清楚第4个,其余3个自然而然也就懂了。

2. 各个参数含义及作用

参数名称参数类型含义作用
corePoolSizeint核心线程池大小它的线程数量大小决定了添加的任务是开辟新的线程去执行,还是放到workQueue任务队列中去
maximumPoolSizeint最大线程池大小线程池中的最大线程数量,这个参数会根据你使用的workQueue任务队列的类型,决定线程池会开辟的最大线程数量
keepAliveTimelong线程存活时间当线程池中空闲线程数量超过corePoolSize时,多余的线程会在多长时间内被销毁
unitTimeUnitkeepAliveTime的单位定下keepAliveTime的单位
workQueueBlockingQueue线程等待队列被添加到线程池中,但尚未被执行的任务;

它一般分为直接提交队列(SynchronousQueue)、有界任务队列(ArrayBlockingQueue)、无界任务队列(LinkedBlockingQueue)、优先任务队列(PriorityBlockingQueue)
threadFactoryThreadFactory线程创建工厂用于创建线程
handlerRejectedExecutionHandler拒绝策略当任务太多来不及处理时,如何拒绝任务;

自带的拒绝策略有:AbortPolicy策略、CallerRunsPolicy策略、DiscardOledestPolicy策略、DiscardPolicy策略

一般来说,如果我们要自定义线程池,重载ThreadPoolExecutor类的构造方法,按自己的需要,更改以上参数即可。

3.JDK自带线程池(Executors类)

JDK自带有5种线程池,存在于Executors类中,如下所示:

  • FixedThreadPool
public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
}
  • WorkStealingPool
public static ExecutorService newWorkStealingPool(int parallelism) {
        return new ForkJoinPool
            (parallelism,
             ForkJoinPool.defaultForkJoinWorkerThreadFactory,
             null, true);
}
  • CachedThreadPool
public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
}
  • ScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
        return new ScheduledThreadPoolExecutor(corePoolSize);
}
  • SingleThreadExecutor
public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
}

其中WorkStealingPool为JDK1.8新增的线程池。

由于JDK自带的线程池可能会导致OOM(Out Of Memory)或者系统资源耗尽的问题,因此在实际开发中,一般不用JDK自带的线程池,多使用自定义的线程池。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值