java多线程

目录

一、线程状态:

二、多线程实现方式

三、线程池


一、线程状态:

  • 新建状态(new):创建线程对象之后;
  • 就绪状态(Runnable):调用start()方法之后;
  • 运行状态(Running):调用run(),即处于就绪状态的线程获取cpu资源之后;
  • 阻塞状态(Blocked):运行中的线程由于某种原因放弃cpu资源,停止执行;
    • 等待阻塞:运行中的线程执行wait()方法,进入等待;
    • 同步阻塞:运行中的线程申请同步锁中的资源失败进入阻塞;
    • 其他阻塞:sleep()、join()、发出io请求时线程会进入阻塞;
  • 死亡状态(Dead):线程执行完成或因异常退出线程。

二、多线程实现方式

  • 继承Thread,重写run()
Thread t = new MyThread();
t.start();
  • 实现Runnable,实现run()方法
// 创建一个Runnable实现类的对象
Runnable myRunnable = new MyRunnable(); 
Thread thread1 = new Thread(myRunnable); 
thread1.start();
  • 使用Callable和Future,实现call()方法
// 创建MyCallable对象
Callable<Integer> myCallable = new MyCallable();    
FutureTask<Integer> ft = new FutureTask<Integer>(myCallable);
Thread t = new Thread(ft); 
t.start();
//获取线程返回结果
int a = ft.get(); 
  • 线程池

三、线程池

  • Executor:线程池最上层接口,提供execute(Runnable run)执行异步任务;
  • ExecutorService:线程池服务接口,提供一系列服务方法;
public interface ExecutorService extends Executor {
    
    // 执行完现有任务,停止接受新任务
    void shutdown();
    
    // 现有任务停止(不一定成功),忽略等待任务,停止接受新任务,返回未执行完的任务列表
    List<Runnable> shutdownNow();
    
    // 只要执行过shutdown()返回 true
    boolean isShutdown();
    
    // 所有任务都已完成,则返回 true
    boolean isTerminated();
    
    // 阻塞当前线程,直到所有任务(正在执行和等待)完成执行、超时、异常
    boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException;
    
    // 返回call()方法返回值
    <T> Future<T> submit(Callable<T> task);
    
    // 执行Runnable的run()方法之后,Future.get()返回传入的result
    <T> Future<T> submit(Runnable task, T result);
    
    // 执行Runnable的run()方法之后,Future.get()返回null
    Future<?> submit(Runnable task);
    
    // 执行给定的任务,当所有任务完成时,返回保持任务状态和结果的 Future 列表
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
        throws InterruptedException;
        
    // 执行给定的任务,当所有任务完成或超时期满时,返回保持任务状态和结果的 Future 列表
    <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
            long timeout, TimeUnit unit)
        throws InterruptedException;
    
    // 执行给定的任务,如果某个任务已成功完成(也就是未抛出异常),则返回其结果
    <T> T invokeAny(Collection<? extends Callable<T>> tasks)
        throws InterruptedException, ExecutionException;
    
  // 执行给定的任务,如果在给定的超时期满前某个任务已成功完成(也就是未抛出异常),则返回其结果
    <T> T invokeAny(Collection<? extends Callable<T>> tasks,
            long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}
  • AbstractExecutorService:抽象类,实现了除shutdown()、shutdownNow()、execute()、isShutdown()、isTerminated()以外的方法;其中submit(Runnable task)内部将task转换为FutureTask对象并调用execute();
  • ThreadPoolExecutor:线程池实现类
    • corePoolSize:线程池大小,提交一个任务,当线程池大小小于corePoolSize时新建一个线程;
    • maximumPoolSize:最大线程池大小,当任务队列满了,且已创建线程数小于maximumPoolSize时,会创建新线程执行任务,任务执行完会回收线程至线程池大小,对于无界队列该参数无效;
    • keepAliveTime:当线程池大于corePoolSize,且线程空闲时间超过keepAliveTime,回收线程至corePoolSize大小;
      • 判断线程超时方式:在 keepAliveTime 的时间内 poll 不到任务则任务超时;
    • unit:存活时间单位NANOSECONDS(纳秒),MICROSECONDS(微妙),MILLISECONDS(毫秒),SECONDS(秒),MINUTES(分),HOURS(小时),DAYS(天);
    • workQueue:任务队列
      • SynchronousQueue:直接提交,即该队列没有大小(容量为0),只有把当前任务提交给线程才能新增;(此队列可防止具有内部依赖的任务执行时出现锁)
      • LinkedBlockingQueue:无界队列,队列无大小,可以无限添加任务;(防止任务丢失)
      • ArrayBlockingQueue:有界队列,固定大小,超过大小无法添加;(防止资源耗尽,JDK不推荐)

corePoolSize、maximumPollSize、workQueue关系:新增一个任务

  • 如果线程池大小 < corePoolSize,新增线程;
  • 如果线程池大小 >= corePoolSize,将任务加入任务队列;
  • 如果无法加入队列(队列类型或队列大小不支持),新增线程至maximumPoolSize大小;
  • 如果线程池大小 >= maximumPoolSize大小,执行拒绝策略。
    • threadFactory:线程工厂,用于创建新线程,同一工厂创建的线程属于同一ThreadGroup;
    • handler:拒绝策略(当线程池和队列都满时)
      • ThreadPoolExecutor.AbortPoilcy:直接抛出异常;
      • ThreadPoolExecutor.CallerRunsPoilcy:调用者所在线程执行该任务,可减缓提交任务的速度;
      • ThreadPoolExecutor.DiscardPoilcy:删除无法执行的任务;
      • ThreadPoolExecutor.DiscardOldestPoilcy:删除任务队列头部的任务。
  • Executors工厂方式默认实现了四种创建线程池的方式
    • Executors.newCachedThreadPool() 提供了无界线程池,可以进行自动线程回收;
      public static ExecutorService newCachedThreadPool() {
              return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 
                                           60L, TimeUnit.SECONDS,
                                            new SynchronousQueue<Runnable>());
      } 
    • Executors.newFixedThreadPool(int) 提供了固定大小线程池,内部使用无界队列;
      public static ExecutorService newFixedThreadPool(int nThreads) {
              return new ThreadPoolExecutor(nThreads, nThreads,
                                            0L, TimeUnit.MILLISECONDS, 
                                           new LinkedBlockingQueue<Runnable>());
       }
    • Executors.newScheduledThreadPool(int) 提供了固定大小线程池,支持定时及周期性任务执行;
      • DelayedWorkQueue:一个无界队列,它能按一定的顺序对工作队列中的元素进行排列。
        public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) { 
               return new ScheduledThreadPoolExecutor(corePoolSize);
        }
        public ScheduledThreadPoolExecutor(int corePoolSize) {
                super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, 
                     new DelayedWorkQueue());
        } 
    • Executors.newSingleThreadExecutor() 提供了单个后台线程。
      public static ScheduledExecutorService newSingleThreadScheduledExecutor() { 
             return new DelegatedScheduledExecutorService 
                 (new ScheduledThreadPoolExecutor(1)); 
      } 
    • Executors.newFixedThreadPool(int) 提供了固定大小线程池,内部使用无界队列;
      public static ScheduledExecutorService newSingleThreadScheduledExecutor() { 
             return new DelegatedScheduledExecutorService 
                 (new ScheduledThreadPoolExecutor(1)); 
      } 

线程池选择:不推荐使用Executors,使用ThreadPoolExecutor更明确运行规则。

  • 任务类型
    • CPU密集型:需要做很多判断、计算等CPU动作的任务;cpu密集型任务对cpu需求较大,应配置尽可能小的线程池大小:n+1;
    • IO密集型:需要做很多写硬盘、读硬盘的操作;io密集型任务对cpu需求不大,因为io操作不占用cpu,可以配置多个线程池:2n+1。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值