美文网首页
java运行原理分析、线程运行机制

java运行原理分析、线程运行机制

作者: 老不经事儿 | 来源:发表于2020-01-05 01:03 被阅读0次

有道云笔记地址

一. 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(空闲)的情况下,被终止的等待时间

相关文章

网友评论

      本文标题:java运行原理分析、线程运行机制

      本文链接:https://www.haomeiwen.com/subject/hjhqactx.html