14.1-线程及执行器

什么是线程:

线程是操作系统运行的最小单元;进程里包含了多个线程,他们处理不同的任务,组成了一个应用或者一个系统的整体逻辑。

  • Thread.yield():让步,当一个线程执行yield()方法,证明该线程执行让步,让其他线程有可能的获取资源运行。

  • Thead.join(): 加入,当一个线程执行join(),证明该线程执行加入操作,会终止当前正在运行的线程,开始执行join的线程。

  • Thread 优先级:Thread.currentThread().setPrority(value);value=Max_prority;Norm_priority;Min_priority;三种不同的优先等级;

  • Thread.setDaemon(boolean);设置当前线程为后台线程,后台线程要在start之前调用才有效。后台线程,是指程序运行的时候在后台提供一种通用服务的线程,且这种线程并不属于程序中不可或缺的部分;只要有任何非后台线程在运行,程序就不会终止。

  • 实现线程的方式:

    1.继承Thread
    2.实现Runable接口
    3.实现Callable,和Runable的区别是有回调方法。
    区别 :实现Runable接口扩展性更好,因为继承只能单向继承

  • sleep和wait的区别
    最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁。wait 通常被用于线程间交互,sleep 通常被用于暂停执行。

public class LifeOff implements Runnable{
private int countDown=10;
private static int taskCount=0;
private final int id=taskCount++;
    public LifeOff(int countDown) {
        this.countDown = countDown;
    }
    public LifeOff() { }
    @Override
    public void run() {
        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        while (countDown-->0){
            System.out.print(status());
        Thread.yield();//让步
    }
}
public String status(){
    return "#"+Thread.currentThread().getName()+"("+(countDown>0 ? countDown:"lifeoff!\n")+")";
}
}

Exector(执行器)

Exector会统一管理线程。

  • newCachedThreadPool会为每一个任务创建一个线程。
ExecutorService executor = Executors.newCachedThreadPool();
executor.execute(new LifeOff());
executor.shutdown();
  • newFixedThreadPool会创建固定数量的线程来执行任务。
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.execute(new LifeOff());
executor.shutdown();
  • newSingleThreadExector会创建一个线程来执行任务。如有多个任务,会排队加载任务。执行一个结束,才会处理下一个任务。
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(new LifeOff());
executor.shutdown();
  • newScheduledThreadPool:可以延时启动,定时启动的线程池,适用于需要多个后台线程执行周期任务的场景。
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);

for (int i = 0; i < 15; i = i + 5) {
    pool.schedule(() -> System.out.println("我被执行了,当前时间" + new Date()), i, TimeUnit.SECONDS);
}
pool.shutdown();

newScheduledThreadPool

创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

  //创建线程池  进行线程优化处理
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                    5,//核心线程数量,核心池的大小
                    20,//线程池最大线程数
                    30,//表示线程没有任务执行时最多保持多久时间会终止
                    TimeUnit.SECONDS,//时间单位
                    new LinkedBlockingQueue<Runnable>(),//任务队列,用来存储等待执行的任务
                    Executors.defaultThreadFactory(),//线程工厂,如何去创建线程的
                    new ThreadPoolExecutor.AbortPolicy()//异常的捕捉器
            );
            //获得要执行的线程任务,会由线程此来管理
            executor.execute(new Runnable()

构造方法
public ThreadPoolExecutor(int corePoolSize,//核心池的大小
int maximumPoolSize,//线程池最大线程数
long keepAliveTime,//保持时间/额外线程的存活时间
TimeUnit unit,//时间单位
BlockingQueue workQueue,//任务队列
ThreadFactory threadFactory,//线程工厂
RejectedExecutionHandler handler) //异常的捕捉器

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

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

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

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

     TimeUnit.DAYS;               //天
     TimeUnit.HOURS;             //小时
     TimeUnit.MINUTES;           //分钟
     TimeUnit.SECONDS;           //秒
     TimeUnit.MILLISECONDS;      //毫秒
     TimeUnit.MICROSECONDS;      //微妙
     TimeUnit.NANOSECONDS;       //纳秒
    
  5. workQueue : 任务队列,是一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,参考BlockingQueue

     ArrayBlockingQueue;
     LinkedBlockingQueue;
     SynchronousQueue;
    
  6. threadFactory : 线程工厂,如何去创建线程的

  7. handler : 任务队列添加异常的捕捉器,参考 RejectedExecutionHandler

    ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
    ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
    ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
    ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务

发布了118 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chentaishan/article/details/104940961