线程基础(1)

  • 内存基本框架

内存简单模型.png
内存简单模型.png

1.方法区为存放类的描述信息
2.栈中存放一些局部变量表、帧栈、操作数栈等
3.堆上存放着new出来的具体对象(数据组织)
4.PC寄存器存放着执行的指令内存地址
5.执行引擎联接寄存器、堆、栈等,进行代码、数据的运算判断

  • java栈

    栈是线程私有的,存储对方法的描述,一般栈中运行的数据,在方法执行完成后,会进行GC
    栈中存放:局部变量表、操作数栈(c=a+b这样的代码逻辑)
    局部变量表(方法中的参数、static、返回值等信息的描述)
局部变量表.png

方法调用形成帧栈

简单帧栈.png
  • 栈、堆、方法区之间的联系

堆、栈、方法区.png

1.方法区存放类的描述
2.堆放置new出的实例
3.栈放置局部变量表等

  • 基础词汇

    • 程序:指令、数据及其组织形式的描述。(指令:加减的命令。数据:理解为java对象所拥有的属性,比如年龄、姓名等。组织形式:即加减操作代码和对象所携带的数据在JVM中如何运行的描述。)
    • 进程:理解为一个程序(微信的代码及其背后的各种数据)的真正的运行实例。(JVM是铁轨的话,程序即为圣诞老人-代码和礼物-数据,进程就是和谐驯鹿号,程序根据礼物派发地,进行if、for等操作跳转。)进程是线程的容器。
    • 线程:是操作系统能够进行运算调度的最小单位,一条线程指的是进程中一个单一顺序的控制流(if、for代码逻辑)。【和谐号中有好多圣诞老人的克隆人,即许多一样的代码分布到不同的车厢(一个车厢就是一个线程的调用栈)】
    • 调度:将cpu计算资源分配给不同的线程。
    • 并行 : 多台计算机或者多个CPU实例同时处理同一段逻辑,比如10台计算机同时计算1到100的和,不涉及资源共享(春运10个窗口开始同时买火车票,假设火车票无限量且无座次限制)
    • 并发:CPU通过调度算法处理同一段逻辑的时候,涉及共享资源。(两个人同时买火车票最后一张,此时就要商量下谁更紧急,此时车票数量有限制)
  • 正传

有了以上的前传,应该会了解些时代背景了,溜哒同学表示以上一定会有错误,请各位大虾批评指正。
多线程问题,即多个进程跑同一段逻辑的时候,因涉及共享资源,不同优先级的线程按照不同执行顺序执行会出现不一样的结果。我们要处理的就是控制多线程控制流的执行,保证线程按照一定顺序执行。

多线程处理同一数据.png

CPU1命令dog1从a点前进100米到b点,CPU2命令dog2从b点倒退100米到a点,代码书写的是,先前进100米到b点,再后退100米到a点。但是两条线程执行调度并不是一定按照我们代码书写的希望所做,很可能前进了50米,然后后退了20米,再前进..后退..
问题出现在,两个人通过同一个遥控器在遥控同一个dog,第一个可能按了前进,紧接着第二个人按了后退。
那么如何才能保证先前进100米,再后退100米呢?这就需要第一个人拿到遥控器先操作完100米,然后把遥控器交给第二个人,第二个人来操作后退的100米。那么问题来了,两人争夺遥控器,其实是争夺遥控器的使用权,代码中如何才能判断谁有使用权呢?这时可以想一下通用的一种分布式锁的实现——在redis中设置一个标记,setIfabsent()可以判断如果redis中没有这个key,就set进一个值,如果有就set不进去,能set进去就能锁住这段代码!(集群中的定时任务,10台机器都想跑同一个定时任务,那么哪台机器在redis中设定了该值即获取了该锁,那么就执行任务,其他的9台直接过掉)。
回到遥控器的使用权这里,道理一样,哪个人(线程)获得执行权(锁)就能遥控dog,那么这个锁放到哪里呢?java提供了自己的锁机制。

1.synchronized
使用synchronized

public void drink(){
   synchronized(this){
       // 对象锁,调用该方法的对象使用的锁
   }
}
public synchronized void eat(){
    // 对象锁,调用该方法的对象使用的锁
}
public void paly(){
    Object obj = new Object();
    synchronized(obj){
       // 对象锁,使用object对象锁
    }
}
public void laugh(){
   synchronized(Object.class){
       // 类锁
   }
}

当多个线程调用某个被synchronized修饰的代码部分的时候就会进行获取锁,执行,放开锁的过程。溜哒同学觉得用天朝高速收费站来看锁机制对理解这玩意儿还是有点帮助的。
我们先说this锁即对象锁,就像八达岭高速收费站那里,好多收费站,好多车来过路,每辆车都是一个对象,而每个收费站都是被synchronized修饰的代码,若想通过执行代码,就需要获取锁,即那计费卡或者ETC上登记。每个线程拥有自己的调用栈,栈中包含着对象(堆中才是,栈中撑死算引用),帧栈(函数调用)等。每个线程用自己的对象锁来执行帧栈中的代码,其实线程间是不存在调用交叉的。当然这时候,我们只是利用多线程,更多的利用CPU资源来完成任务,这里并不涉及共享资源,也就没有多线程问题。下图里,每个线程在自己的栈中跑的很欢实,到了收费站,拿卡,登记等。自己做自己的事情就好。这比一条告诉公路,一堆汽车来过路,处理的快很多。

被锁代码没有共同资源的情况.png

上图中其实没有必要加锁,但是如果到了春运大流量的时候,过路卡稀缺的时候就需要加锁了

争抢共同资源的情况.png

上图中,每辆汽车都想先过去,好早点回家过年,但是就3张了,谁先拿到谁先过路,谁就先执行代码。比如类锁,JVM全局中某个Class对象只有一个,哪条线程拿到,哪条先执行。其实这只是锁的一个简单理解。用锁,我们重点关注的是处理共享资源问题。
我们把这张图调整下,这样理解,理解为六个人,每个人拥有一个数字,需要将这个数字放到前方一个又大又破的计算器中,这个计算器只能做从小到大的加和动作,而且每次只能计算两个数。比如:2+3 = 5, 计算完了5之后,才能计算5+6=11的操作(强行扯上关系)

共享资源且有先后顺序.png

可以看到第一步的时候需要1号线程先过去,把他的数字1放到计算器中,他在synchronized代码之前已经获取锁(图中的红色圈),且全局只有这一个锁(比如类锁),虽然其他线程跑的比1号线程快,但是到了synchronized锁住的代码的时候,因为没有通行证,就只能跟那儿等着(阻塞),然后1号线程完成把数放到计算器中,最后它还要把锁交给2号线程,因为我们有一个只能依次向上加和的限制,所以要notify2号线程(线程间通信),然后依次累加计算。这样计算器正常运行,结果如我们所愿。

  • 小结

多线程目的即高效的使用CPU资源,去处理没有共享资源的部分,加快任务执行速度,但是如果到了共享资源的时候,需要看是不是有数据的前后依赖关系,如果有依赖关系,我们需要让线程间通信,哪个线程该先执行,哪个该后执行,最终保证计算正确。

  • 后传

synchronized 其实不只是一个锁的概念,还有一个内存可见性需要我们了解。线程第二季的时候,我们会由synchronized 的内存可见性引出内存可见性和volatile关键字,另外也会提到java5之后的lock锁,可以提前了解下hashtable和ConcurrentHashMap相关的知识。线程通信也是很6的部分,不过也是很难操作的呢!!请各路英雄轻拍,指点。希望慢慢的进步,将来不奢望成为大牛,成个小牛就行,但是不能是肥牛不是。

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

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,697评论 0 11
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,217评论 11 349
  • 写在前面的话: 这篇博客是我从这里“转载”的,为什么转载两个字加“”呢?因为这绝不是简单的复制粘贴,我花了五六个小...
    SmartSean阅读 4,717评论 12 45
  • 昨天和资深的UI设计师聊了一下,说起了当下有很多假的UI,不懂UI只懂作图,说实话,在昨天之前我也属于那一行列,也...
    浅想浅抚阅读 300评论 0 1
  • 将S2I产生的镜像push到openshift Rejistry Rejistry的分类:1)内部镜像仓库:供op...
    IvyFan2017阅读 1,170评论 0 2