"诡异的线程不安全",代码块,同步代码块,对象锁

上一节课我们学习了java的多线程,ArrayList线程不安全和Vector线程安全
这节课我门改变一下
不在主线程里面打印出mylist的长度了而是在子线程中打印mylist的长度
代码改为下面
MyIndex里面


image.png

MyThread下面


image.png

运行结果
image.png

出现了线程不安全的情况 我们在代码中使用的是Vector集合为什么会出现线程不安全的情况呢?
为了解决这个问题 我们需要在子线程外部中加入一个代码块 这个代码块为同步代码块
代码如下
image.png

加入同步代码块,将list对象锁住 即可以解决线程不安全问题
运行结果


image.png

运行多次 结果相同
接下来我们把Vector换成ArrayList试一下
MyIndex文件中
image.png

运行结果
image.png

接下来我们了解一下代码块
image.png

代码块就是用{}括起来的部分组成个代码块 代码块是有块级作用域的 嵌套的代码块子代码块可以访问父代码块里的内容
在我们的MyIndex里面写入如下
image.png

可以看见输出内容处a报错了 这就是代码块的作用域 外部访问不到a
但是写成下面这样
image.png

就不报错了

运行结果


image.png

嵌套代码块子代码块可以访问父代码块里的a
一般我们在方法中不会这样写,因为可读性并不高
image.png

那么代码块主要用在哪里呢?
1.在类里面
构造代码块
image.png

为了演示我们在Core里创建个test文件
image.png

代码如下
image.png

这时我们在MyIndex里面使用一下
image.png

运行结果
image.png

可以看出将构造代码块放在上面 构造代码块先执行了
接下来在我们test文件里加入一个构造代码块
image.png

运行结果
image.png

接下来在test中将代码块1和2位置互换
image.png

运行结果
image.png

静态代码块
image.png

用static关键字加上大括号包起来的代码块
静态代码块只会执行一次
为什么只会执行一次呢?
下面看一下代码 test文件中
image.png

运行结果
image.png

可以看到静态代码块先执行了

但是我们要知道 静态代码块 和 构造代码块 构造函数并不在同一阶段执行
接下来我们演示一下 在MyIndex里面多实例化几次test
代码如下


image.png

运行结果
image.png

静态代码块只会执行一次是因为他只在类的初始化阶段执行 而构造代码块和构造函数在类的实例化阶段执行
还有一个有趣的现象是
image.png

演示一下 test中代码定义一个静态变量
image.png

这时如果我不在MyIndex里面实例化代码
运行结果如下
image.png

什么都没输出 因为我没实例化
其实类装载是有过程的 装载-》验证-》解析-》初始化-》实例化等过程
但是我们在MyIndex里面调用一下name
image.png

运行结果
image.png

可以看见执行了静态代码块里面的内容 因为我们对变量进行调用了 触发了类装载的过程了
接下来再看下同步代码块
image.png

image.png

同步代码块 其中Vector里面有sync那个同步方法 为什么还会出现线程不安全 为什么需要在子线程里面将list锁住呢
问题在于什么时候释放锁 是因为Vector代码中锁释放的时间不一样 Vector中锁的是this对象Vector实例化过后的对象
其中Vector里面有一个add方法 这个方法执行完之后 锁就释放了 这时另外一个线程对list操作的时候 就可以得到锁了 所以会出现得到size结果不一致的现象
但是我在MyThread中加入同步代码块时 需要将同步代码块中的内容执行完毕 才释放锁
也就是我们下面的代码
image.png

这时add执行完成之后 去计算mylist的长度时锁还没被释放
接下来我们在Core里面建一个MyObj.java文件
image.png

接下来修改一下MyThread线程代码
使其支持两个方法 先不使用ArrayList和Vector 先传入MyObj参数
image.png

接下来来到MyIndex.java文件
实例化MyObj 传入子线程
image.png

依然对MyThread循环500次 看一下运行效果 等一下要修改一下MyObj里面的源码(因为ArrayList里面没法改)
image.png

运行结果
image.png

出现了线程不安全
接下来在MyObj里面函数部分加入同步关键字synchronized
image.png

运行结果
image.png

依然还是线程不安全的
那么如何解决呢?
这时来到MyThread类
image.png

加入同步代码块 将myObj锁住 一旦锁住之后 代码块里面的内容只能有一个线程执行 下一个线程只有等上一个线程执行完成之后才能执行
运行结果一定是500的倍数
结果如下
image.png

但是如果我们不想使用同步代码块怎么办呢?
MyThread里面
image.png

MyObj里面
image.png

运行结果
image.png

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

推荐阅读更多精彩内容

  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,448评论 1 15
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,954评论 1 18
  • 一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。...
    阿敏其人阅读 2,611评论 0 13
  • 该文章转自:http://blog.csdn.net/evankaka/article/details/44153...
    加来依蓝阅读 7,340评论 3 87
  • 侄女大概六七岁左右,也是一名留守儿童,家里的奶奶带着她,性格很是内向,甚至有一点怪癖,我回家的那天正好遇到她在桥头...
    无_念阅读 521评论 2 3