java 线程及线程池解析

java 创建线程的方式

1.继承 Thread 类实现多线程

  • start方法

start()用来启动一个线程,当调用start方法后,系统才会开启一个新的线程来执行用户定义的子任务,在这个过程中,会为相应的线程分配需要的资源。

  • run方法

run()方法是不需要用户来调用的,当通过start方法启动一个线程之后,当线程获得了CPU执行时间,便进入run方法体去执行具体的任务。注意,继承Thread类必须重写run方法,在run方法中定义具体要执行的任务。

class MyThread extends Thread{

@Override

public void run() {

synchronized (object) {

i++;

System.out.println("i:"+i);

try {

System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态");

Thread.currentThread().sleep(10000);

} catch (InterruptedException e) {

// TODO: handle exception

}

System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束");

i++;

System.out.println("i:"+i);

}

}

}


2.实现 Runnable 接口

只是一个接口,它里面只有一个run()方法,没有start()方法。

3.实现 Callable 接口

  • Executor 框架中还有一种方法可以实现异步,那就是实现 Callable 接口并重写call方法。
  • 虽然是实现 Callable ,但是在 Executor 实际运行时,会将 Runnable 的实例或 Callable 的实例转化为 RunnableFuture 的实例。
  • RunnableFuture 继承了 Runnable 和 Future 接口,这点将在下文详细解释。了解到这些 ,那么它和 Runnable 有什么不同呢?
  • Callable 与 Runnable 相比不同点:

Callable 可以在任务结束的时候提供一个返回值,Runnable 无法提供这个功能。

Callable 的 call 方法分可以抛出异常,而 Runnable 的 run 方法不能抛出异常。

4.线程池

线程池就是有N个子线程共同在运行的线程组合。

线程池原理

线程池可以减少创建和销毁线程的次数,从而减少系统资源 的消耗,当一个任务提交到线程池时

  • 首先判断核心线程池中的线程是否已经满了,如果没满,则创建一个核心线 程执行任务,否则进入下一步
  • 判断工作队列是否已满,没有满则加入工作队列,否则执行下一步
  • 判断线程数是否达到了最大值,如果不是,则创建非核心线程执行任务,否 则执行饱和策略,默认抛出异常

ThreadPoolExecutor

java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。

  • Executor是一个顶层接口,在它里面只声明了一个方法execute(Runnable),返回值为void,参数为Runnable类型,从字面意思可以理解,就是用来执行传进去的任务的
  • ExecutorService接口继承了Executor接口,并声明了一些方法:submit、invokeAll、invokeAny以及shutDown等;
  • 抽象类AbstractExecutorService实现了ExecutorService接口,基本实现了ExecutorService中声明的所有方法。


java 线程及线程池解析



分享到:


相關文章: