Java基础(1)

一、Java程序运行原理


线程独占:每个线程都会有它独立的空间,随线程生命周期而创建和销毁;

线程共享:所有线程能访问这块内存数据,随虚拟机或者GC而创建和销毁;


1.方法区(线程共享):

JVM用来存储加载的类信息、常量、静态变量、编译后的代码等数据,虚拟机规范中这是一个逻辑区划。

HotSpot虚拟机使用永久代来实现方法区,使得HotSpot虚拟机的垃圾收集器可以像管理堆内存一样来管理这部分内存,能省去专门为方法区编写内存管理代码工作。所以开发者喜欢将方法区称为永久代,本质上两者并不等价,对于其他虚拟机来说不存在永久代的概念。

当方法区无法满足内存分配需求时,将会抛OutOfMemoryError异常。

运行时常量池

运行时常量池是方法区的一部分。

class文件除了有类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后加入方法区的运行时常量池中存放。

2.堆内存(线程共享):

JVM管理的最大的一块内存区域,存放着对象的实例,是线程共享区。

堆是垃圾收集器管理的主要区域,因此也被称为“GC堆”。JVM启动时创建,存放对象的实例。

垃圾回收器主要就是管理堆内存。如果满了,就会出现OutOfMemoryError,可通过参数 -Xmx -Xms 来指定运行时堆内存的大小。

JAVA堆的分类:

从内存回收的角度上看,可分为新生代(Eden空间,From Survivor空间、To Survivor空间)及老年代(Tenured Gen)

从内存分配的角度上看,为了解决分配内存时的线程安全性问题,线程共享的JAVA堆中可能划分出多个线程私有的分配缓冲区(TLAB)



3.虚拟机栈(线程独占):

每个线程有一个私有的栈,随着线程的创建而创建,生命周期与线程相同。线程栈由多个栈帧组成。一个线程会执行一个或多个方法,一个方法对应一个栈帧。

栈帧内容包含:局部变量表、操作数栈、动态链接、方法返回地址、附加信息等。


局部变量表存放了编译期可知的各种基本数据类型和对象引用类型。通常我们所说的“栈内存”指的就是局部变量表这一部分。

局部变量表所需的内存空间在编译期间完成分配,当进入一个方法时,这个方法需要在帧分配多少内存是固定的,运行期间不会改变局部变量表的大小。

方法的调用到执行完毕,对应的就是栈帧的入栈和出栈的过程。

栈内存默认最大值是1M,栈的大小可以固定也可以动态扩展。

在固定大小的情况下,当栈调用深度大于JVM所允许的范围,会抛出StackOverflowError异常。

在动态扩展的情况下,若扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。


4.本地方法栈(线程独占):和虚拟机栈功能类似,虚拟机栈是为虚拟机执行JAVA方法而准备的,本地方法栈是为虚拟机使用Native方法而准备的。

超出大小后,也会抛出StackOverFlowError


5.程序计数器(线程独占):记录当前线程执行字节码的位置,存储的是字节码指令地址。

CPU同一时间,只会执行一条线程中的指令。JVM多线程轮流切换并分配CPU执行时间的方式。切换线程后,需要通过程序计数器来恢复正确的执行位置。




二、线程状态

1.线程状态

6个状态定义:java.lang.Thread.State:

New:尚未启动的线程的线程状态

Runnable:可运行线程的线程状态,等待cpu调度

Blocked:线程阻塞等待监视器锁定的线程状态。处于synchronized同步代码块或方法中被阻塞。

Waiting:等待线程的线程状态,依赖另一个线程通知。

              (e.g.:Object.wait、Thread.join、LockSupport.park)

Timed Waiting:具有指定等待时间的等待线程的线程状态。

               (e.g.:Thread.sleep、Object.wait、Thread.join、LockSupport.parkNanos、LockSupport.parkUntil)

Terminated:终止线程的线程状态。线程正常完成执行或者出现异常

2.线程状态流程图


3.正确的线程终止

(1)通过interrupted方法

Thread.java类中提供了;两种方法进行判断,分别是:interrupted()和isInterrupted()方法。

Interrupted():测试当前线程是否已经中断。执行后具有清除中断状态的功能。

isInterrupted():测试线程都否已经中断。没有清除中断状态的功能。


如果目标线程在调用Object class的wait()、wait(long)或wait(long,int)方法、join()、join(long,int)或sleep(long,int)方法时被阻塞,那么Interrupt会生效,该线程的中断状态将被清除,抛出InterruptedException异常;

如果目标线程是被I/O或者NIO中的Channel所阻塞,同样。I/O操作会被中断或者返回特殊异常值。达到终止线程的目的;

如果以上条件都不满足,则会设置此线程的中断状态。


为何stop()方法被弃用?

stop()方法太过于暴力,会强行把执行一半的线程终止。这样会就不会保证线程的资源正确释放,通常是没有给与线程完成资源释放工作的机会,因此会导致程序工作在不确定的状态下。造成数据的不同步。

(2)通过自定义的标志

代码逻辑中,增加一个判断,用来控制线程执行的终止。如demo中的flag。


三、线程通信

1.通信方式分类

(1)文件共享

如demo所示,一个线程写数据,一个线程读数据


(因为sleep方法throw了InterruptedException,所以外面要包一层try..catch)

(2)网络共享

调用http接口等

(3)变量共享

利用内存的公共区域来实现共享


(4)jdk提供的线程协作API

① suspend/resume (已弃用,容易造成死锁)

缺点1:如果加了同步代码块,suspend并不会像wait一样释放锁,故容易写出死锁代码,导致线程之间死锁

缺点2:消费者和生产者的执行顺序随机,导致生产者通知(resume)提前,使消费者一直等待(suspend),最终导致程序永久挂起

② wait/notify

优点:wait方法导致当前线程等待,加入该对象的等待集合中,并且放弃当前持有的对象锁;

notify/notifyAll方法唤醒一个或所有正在等待这个对象锁的线程。

缺点:虽然wait会自动解锁,但对顺序有要求,必须要在wait方法后调用notify,否则线程永远处于waiting状态

③ park/unpark

优点:park和unpark对调用顺序没有要求,可以多次调用unpark后再调用park。但是不能叠加,第一次park拿到"许可"后,后续的park需要再次调用unpark获得许可。类似一个标志位。

缺点:同步代码中也不会释放锁


2.伪唤醒

伪唤醒是指线程并非因notify、notifyall、unpark等api调用而唤醒,而是更底层原因导致的。

官方建议在循环中检查线程等待条件,原因是处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。


多线程协作典型场景: 生产者-消费者模型。(线程阻塞、线程唤醒)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,723评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,003评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,512评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,825评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,874评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,841评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,812评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,582评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,033评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,309评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,450评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,158评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,789评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,409评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,609评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,440评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,357评论 2 352

推荐阅读更多精彩内容

  • 昨日凉风袭来,温度骤降,夏日的尾巴已经离开,秋的凉意即将到来,往日所难以忍受的酷暑在时间的流逝中终于将要离去,似乎...
    伊凌L阅读 126评论 0 0
  • 1.从本篇文章/音频/视频中我学到的最重要的概念 有时候成功与失败其实就是自己心中是否有执念 2.我在本篇文章/音...
    旅一22李雨洁阅读 197评论 0 0
  • 灵感就是瞬间碰撞的思想火花!许多神来之笔就会在眼前显现! 关...
    春暖花开_8019阅读 277评论 1 1
  • bbaiggey_bigdata的博客专注大数据 ---架构设计 http://blog.csdn.net/bba...
    Albert陈凯阅读 139评论 0 0
  • 关于本人 本专业特殊教育,服役某快递公司6年,目前专职于淘宝。 从公司离职之后,我一直在思考自己究竟该干什么。自己...
    Whyya阅读 370评论 0 2