一. JVM运行时数据分区
java文件编译为class字节码文件后,交给jvm继续执行
1. 一般来说,数据区分为:共享内存、线程独占内存
2. 说明
方法区:存类信息
堆内存:存对象数据
虚拟机栈:存放执行的线程,线程中的方法即为栈帧,根据jvm规范:一个线程默认最大栈大小为1MB
本地方法栈:存native方法
程序计数器:存放线程执行的位置:class字节码指令地址
执行引擎、本地库接口、本地方法库,这三个一般是随不同的操作系统上运行的jvm来提供,正所谓:一次编写,到处运行
2. 查看class文件内容
javap -v Demo.class > Info.txt
javap命令输出的是操作符,对应的是class文件中的指令码
二、线程状态
1. java.lang.Thread.State 定义了线程的6个状态
public enum State {
/**
* Thread state for a thread which has not yet started.
* 尚未启动
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
* 可运行,等待cpu调度
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
* 线程阻塞等待监视器锁定的状态,
* 处于synchronized同步代码块或方法中被阻塞
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*
* 等待线程的状态:
* 不带超时的方式:Object.wait(),Thread.join(),LockSupport.park()
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*
* 具有指定等待时间的等待线程的状态:
* 带超时的方式:Thread.sleep(long),Object.wait(long),Thread.join(long)
* LockSupport.parkNanos(), LockSupport.parkUntil()
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*
* 终止状态: 线程正常完成执行或者出现异常
*/
TERMINATED;
}
2. 线程状态的变化:
线程终止之后,再进行调用,会抛出IllegalThreadStateException异常
3. 线程终止的方式
Thread.stop() 会强行终止当前线程,无法使程序保持操作的原子性,会破坏线程安全
正确的方式:
StopThread thread = new StopThread();
thread.interrupt();
4. 内屏屏障
cpu的高速缓存一般有L1、L2、L3三级缓存,这三级缓存的容量也是有小到大,
多核cpu,一般是每个核都有独立的L1、L2,多核共享一个L3
cpu读取数据时,一般是先从L1寻找,再从L2寻找,再从L3寻找,然后是内存,最后是外存储器(硬盘)
缓存同步协议:
cpu性能优化手段:运行时指令重排
单个cpu单独执行时,指令重排遵循 as-if-serial 语义,即编译器和处理器不会对存在数据依赖关系的操作做重排序
在多核多线程情况下:
1. 高速缓存同步协议无法保证在同一个时间点,各cpu读取到的同意内存地址的数据的值可能时不一致的
2. 指令重排仅在单cpu自己执行的情况下可以保证结果正确,多核多线程时,指令逻辑无法分辨因果关联,可能出现乱序执行,导致程序运行结果错误
处理器提供了两个内存屏障指令(Memery Barrier) 用于解决上述两个问题:
三、线程通信
1. 多线程写作的典型场景:生产者-消费者模型 (线程阻塞、线程唤醒)
2. 线程的挂起(线程等待)、线程的恢复执行(线性唤醒):
suspend()、resume() ,已被弃用,因为在同步代码中,执行suspend()后不会释放锁, 如果在resume()后执行,会容易出现死锁
wait()、notify()和notifyAll(),在同步代码中,执行wait()会释放锁,但也要注意顺序,notify()和notifyAll()必须在wait()之后执行才不会死锁
park()、unpark(),不是基于监视器(锁)实现,所以执行park()后不会对锁有影响,没有执行先后顺序要求.
LockSupport.park(); //进入等待
LockSupport.unpark(consumerThread); //唤醒
四、线程封闭
1. ThreadLocal
ThreadLocal是Java里一种特殊的变量,是一个线程级别变量。
用法:
ThreadLocal<T> var = new ThreadLocal<T>();
会自动在每个线程上创建一个T的副本,副本之间彼此独立,互不影响,在并发模式下是绝对安全的变量。
可以用ThreadLocal存储一些参数,以便于在线程中多个方法中使用,用来代替方法传参的方式。
2. 栈封闭
五、线程池
corePoolSize //核心线程数量(the number of threads to keep in the pool, evenif they are idle, unless {@code allowCoreThreadTimeOut} is set)
maximumPoolSize //线程池最大线程数量(the maximum number of threads to allow in the pool)
keepAliveTime //超过核心线程数量的线程,在没有执行新task(空闲)的情况下,被终止的等待时间