线程与进程

280 阅读4分钟

1.线程与进程

* 1、一个进程可以包含一个或多个线程。(其实你经常听到“多线程”,没有听过“多进程”嘛)* 2、进程存在**堆**和**方法区*** 3、线程存在**程序计数器**和**栈*** 4、堆占最大内存,其为创建时分配的,是多线程共享的,主要存放new创建的对象* 5、方法区也是多线程共享的,主要存放类、常量、静态变量* 6、CPU的基本执行单位是线程(注意!不是进程)* 7、由此,线程需要一个程序计数器记录当前线程要执行的指令地址* 8、当CPU的时间片用完,让出后记录当前执行地址,下次继续执行(时间片轮询)* 9、只有执行Java代码时pc技数器记录的才是下一条指令的地址,执行native方法,则记录的是undefined地址* 10、线程中的栈,只要存储线程局部变量、调用栈帧

实现多线程有两种方式:(自JDK1.5之后有三种,最后一种并不常用)

1.继承Thread类

2.实现Runnable接口(Callable接口)

  1. Runnable的实现方式是实现其接口即可
  2. Thread的实现方式是继承其类
  3. Runnable接口支持多继承,但基本上用不到
  4. Thread实现了Runnable接口并进行了扩展,而Thread和Runnable的实质是实现的关系,不是同类东西,所以Runnable或Thread本身没有可比性。

2.线程池

Future机制

Callable

  • Callable是一个接口,一个函数式接口,也是个泛型接口。call()有返回值,且返回值类型与泛型参数类型相同,且可以抛出异常。Callable可以看作是Runnable接口的补充。
  • Future是为了配合Callable/Runnable而产生的,既然有返回值,那么返回什么?什么时候返回?这些问题其实都可以算在Future机制里。
  • FutureTask实现了RunnableFuture接口,同时具有Runnable、Future的能力,即既可以作为Future得到Callable的返回值,又可以作为一个Runnable。

Executor是一个接口,里面提供了一个execute方法,该方法接收一个Runable参数,

Java标准库提供了ExecutorService接口表示线程池

因为ExecutorService只是接口,Java标准库提供的几个常用实现类有:

  • FixedThreadPool:线程数固定的线程池;
  • CachedThreadPool:线程数根据任务动态调整的线程池;
  • SingleThreadExecutor:仅单线程执行的线程池。
  • 创建这些线程池的方法都被封装到Executors这个类中
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。 ThreadPoolExecutor.DiscardPolicy:丢弃任务,但是不抛出异常。 ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新提交被拒绝的任务 ThreadPoolExecutor.CallerRunsPolicy:由调用线程(提交任务的线程)处理该任务

当初始化一个线程池之后,池中是没有任何用户执行任务的活跃线程的,当新的任务到来时,根据配置的参数其主要的执行任务如下:

  • 若线程池中线程数小于corePoolSize指定的线程数时,每来一个任务,都会创建一个新的线程执行该任务,无论线程池中是否已有空闲的线程;
  • 若当前执行的任务达到了corePoolSize指定的线程数时,也即所有的核心线程都在执行任务时,此时来的新任务会保存在workQueue指定的任务队列中;
  • 当所有的核心线程都在执行任务,并且任务队列中存满了任务,此时若新来了任务,那么线程池将会创建新线程执行任务;
  • 若所有的线程(maximumPoolSize指定的线程数)都在执行任务,并且任务队列也存满了任务时,对于新添加的任务,其都会使用handler所指定的方式对其进行处理。
`ThreadLocal`类是`java.lang`包下的一个类,用于线程内部的数据存储,

给每个方法增加一个context参数非常麻烦,而且有些时候,如果调用链有无法修改源码的第三方库,User对象就传不进去了。

Java标准库提供了一个特殊的ThreadLocal,它可以在一个线程中传递同一个对象。

至此线程的本地变量的本质就清晰了。就是Thread用类似Map的ThreadLocal.ThreadLocalMap数据结构来存储以ThreadLocal类型的变量为Key的数值,并用ThreadLocal来存取删,操作ThreadLocalMap