Java多线程与并发编程笔记
在步入正题之前,简单的说几句,以示对这么伟大的事情留下一个见证。默默的在csdn上看博客啊,下载资料啊,学习新技术啊大概有三年的时间了,以前知识看,拿来用
但是从来没有想到过自己会动手来写文章,毕竟自己的技术不是辣么优秀么,哈哈。。。写的好坏现在真得不重要,最重要的是一个开始,自己可以把所学的知识加深印象一遍,然后还可以记录下来,以后用到了 可以来翻一翻,岂不是一举多得的事情,美哉美哉!下面就开始我的美好的旅程吧,gogogo...
Q1:为什么要用线程池?线程池为什么存在?如果离开线程池我们去手动在我们的service的方法中去创建线程会有什么后果 呢?
As:我们知道为诶个请求创建一个新的线程的开销很大,为每个请求创建新线程的服务器的服务器在创建和销毁线程上花费 的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多。
除了创建和销毁线程的开销之外,活动的线程也消耗系统资源。在一个JVM里创建太多的线程可能会导致系统由于过度 消耗内存而用完内存或者“切换过度”。
所以,为了防止资源不足,服务器应用程序需要一些办法来限制任何给定时处理的请求数目。线程池为线程的生命周期
开销问题和资源不足问题提供了解决方案。
所以,线程资源必须通过线程池提供,不允许在应用中自行显示创建线程。
Q2:创建和销毁线程上系统资源的开销,高在哪里?是上下文和堆栈么?
As:这个资源平时是感受不出来的,cpu创建的线程对象的时候,需要用到我们的java内存模型里面的线程栈,这时候内存里 面是要进行内存空间的开辟与分配的。
操作系统里面的资源狭义上对我们来讲:就是cpu的执行碎片时间和内存。
Q3:Java中Volatile关键字解析?
As:Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的
As:Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized
”;与 synchronized
块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized
的一部分。
volatile主要解决多线程内存不可见问题。对于一写多读,是可以解决变量同步问题的。但是volatile不是线程安全 的,这一点要铭记于心。如果是写的很频繁的话就要小心了,它是会相互覆盖的。
和volatile同级的还有一个叫做原子操作。例如:AtomicInteger,都是基本类型的,这个是线程安全的。
Q4:线程池的工作原理?
As:多线程技术主要用来解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处 理器单元的吞吐能力。
假设线程创建时间+销毁时间远远大于在线程中执行任务的时间,则可以采用线程池,以提高服务器性能。
一个线程池包含以下四个基本租成部分:
1、线程池管理器(ThreadPool):用于创建和管理线程池,包括创建,销毁以及添加新任务;
2、工作线程(PoolWorker):线程池中的线程,在没有任务的时候处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务执行,它主要规定了任务的入口,任 务执行完成后的收尾工作以及任务的执行状态等;
4、任务队列(TaskQueue):用于存放没有处理的任务,提供一中缓冲机智。
里面有两个重要的东西:
1、worker线程队列(工作队列);
2、等待线程队列(任务队列)
真正干活的是worker线程。就是我们初始的线程池的大小:最大值、最小值以及超出时间;
里面会用到线程的状态机制,线程有wait和notify两个状态。因为wait和notify是在同一个锁下面才会有用,所以你
会发现源码里面还会用到同步锁,也就是当我们去等待队列里面的任务的时候。
看一下下面的线程池的结构图: