Java并发学习之多线程间数据共享与隔离可以怎么玩

推荐一个Java学习群523401738每天晚上在腾讯课堂都有一个Java技术学习课,会有老师分享干货,帮助大家分析解答问题,你愿意来学习吗

多线程间数据共享与隔离

什么场景下会用到数据共享?如何实现多线程之间的数据共享?如何确保多线程修改共享变量不会出现并发问题?

本篇博文为基础篇,努力做到让大家一目了然,同时欢迎各路大神的批评指正

主要内容集中在多线程环境下,如何实现安全高效的数据共享和数据隔离

I. 数据共享的几种方式

我们可以先抛开多线程这个前置条件,我们先看下在多个对象之间如何共享数据?

类的公开静态变量,多对象可以直接访问,可算是共享

interface中定义的属性,也可以直接访问,亦可以算是共享

外部配置(如文件中的值,远程的配置属性等),也可以算是都对象共享的资源

那么多线程之间的数据共享,又有什么区别呢?

首先上面的几种,当然也是合乎多线程的数据共享规则的,除此之外,也有一些与众不同的地方,下面就就结合不同的线程使用方式来说道说道

1. 一个Callable/Runnable任务,多个Thread执行

博文《Java并发学习之四种线程创建方式的实现与对比》介绍了线程创建的几种方式,我们知道利用Callbale/Runnable接口来创建线程时,最终都是要丢给Thread来启动线程的

先来个小例子,演示下上面这是个什么场景

主要将目标集中在线程1和线程2的创建上,实例中,只创建了一个task实例,但是起了两个线程,都是将task实例作为参数丢到线程中去调度执行

既然两个线程执行任务时,都是执行的同一个实例--task的run(),方法,那么task实例中的count变量理应就是两个线程共享的了

执行上面的,看下输出

如果数据不是共享的,则不可能出现2;至于为什么都输出2,则涉及到了线程同步的问题,后续再讲

所以,这种场景,就是一个有意思的线程间数据共享了

2. 一个Callable/Runnable对应一个Thread

上面是复用了task任务,如果我们不复用task任务呢,如何实现数据共享?

下面看下一种猥琐的实现方式

相比上面的一种方式,虽然创建了多个task任务,但是共享的数据,放在了一个多任务可以访问的对象内,输出如下,也证明确实属于共享了

3. 数据共享分析小结

上面两种是典型的数据共享方式,虽说表现形式不同,但揪其核心,就一点:

多线程的数据共享其本质依然是共同访问某一个实例的成员属性

为什么这么说?

多个线程,访问同一个数据(or资源),那么这个数据必然有一个载体,java的世界中一切都是对象,所以多个线程访问同一个实例的成员变量,也就能实现多线程之间的数据共享了

讲道理,弄清楚这个核心之后,再看上面的两种玩法

1. 一个Task任务,放在多个Thread中运行

因为只有一个task实例,被多个线程运行,那么task内部的成员,当然可以轻松的实现多线程的数据共享

2. 每个Thread独立运行

因为每个Thread都独立运行一个task任务,task之间的运行彼此独立,所以要实现数据共享,只能借助第三方的实例

即大家都访问一个第三方实例的成员属性,间接的实现多线程数据共享

再简单分析下线程池的使用场景(其实质和上面等同, 殊途同归罢了)

依然是有两种使用方式,公用task和独立的task

II. 数据隔离怎么玩

这个就有点意思了,有了数据共享就有了数据隔离; 有些数据我希望是多线程公用的;但是有些呢,我希望每个线程都是彼此独立互不影响的

上面说了数据共享的本质,反其道而行之,就能摸出数据隔离的本质,每个线程就访问线程内部的数据,不访问共通的数据,不就实现数据隔离了么

说说容易,实际做呢?

1. 一个task就对一个thread

这个就是最简单的方式了,每个thread就新创建一个task实例,那么task内部的成员全都是隔离的,对其他线程而言,都是访问不到的(正常情况下是访问不到的,当然不正常的情况下就说不准了)

2. ThreadLocal 的使用

重点来说一下这个,其实主要也是说如何使用 ThreadLocal 来实现数据隔离

使用 ThreadLocal 来保证变量在线程之间的隔离, 下面是一个简单的演示,两个线程都是在修改threadLocal中的值, 但是两个线程的修改,对彼此而言是独立的

某次输出截图如下,两个线程不会出现乱掉的情况

因为本篇的着力点是介绍数据共享和数据隔离的玩法,所以这里也就简单说下ThreadLocal的实现原理

使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本

使用方式也比较简单,常用的三个方法

III. 注意事项&小结

1. 实例演示多线程数据共享和数据隔离

我们举一个小case,来分别演示下什么东西需要多线程之间的数据共享,什么东西又是需要多线程的数据隔离

诶,到点和女票一起去火锅店开胃了,这家店服务不错,对个用户,一进来就递上菜单,等着顾客勾选完比之后将菜单给后厨,开始准备食材

这个么过程就涉及到了多线程的数据共享和数据隔离

每一桌客户涮火锅的行为,我们比作开了一个线程执行某项任务;

那么有多少桌客户,就有多少个线程了

那么什么是多线程之间共享的呢?即什么东西是每桌客户都有的呢?

菜单

那么什么是多线程之间隔离的呢?即什么东西每桌客户都不一样,是由每桌的客户自己来控制的呢?

客户点的菜单

这么一看,诶,稍微清晰点了,但是又有个问题了,实际上呢,多线程共享的数据,可不仅仅是大家都可以查询这个数据,我们不尽可以查,我们还可以放心大胆的改呢,对比上面的,我一个客户来了菜单,新增一个菜,难不成其他桌的菜单上也新增了这个菜不成???

这个问题就有意思了,这个涉及的起始是另一个问题,多线程之间数据共享的安全性保障(即多线程之间的数据同步),主要表现为

一个线程修改共享数据,其他线程是否可以立马看到

一个线程修改共享数据,是否会被其他线程覆盖掉(而且这个覆盖的逻辑随机不可控)

那么这个问题怎么hold住呢? 精彩分析,欢迎关注下节分享(目前还没产出....)

2. 数据共享

多线程的数据共享其本质依然是共同访问某一个实例的成员属性

为了达到上面这个目标呢,常见的两种使用姿势如下

一个Task任务,被多个线程共同使用,那么Task任务内部的数据都是多线程共享的

一个公共的实例持有需要共享数据,每个线程都访问/修改这个实例的数据

3. 数据隔离

线程内部的数据都是隔离且安全的

借助ThreadLocal, 每个使用该变量的线程提供独立的变量副本

III. 其他

声明

尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见识有限,如有问题,请不吝指正,感激

欢迎关注java一灰灰

更多并发相关学习博文链接

Java并发之 volatile & synchronized 讲解

Java并发学习之Volatile及内存模型探究

Java并发学习之synchronized原理及使用小结

Java并发学习之ReentrantLock的工作原理及使用姿势

Java并发学习之CountDownLatch实现原理及使用姿势

Java并发学习之四种线程创建方式的实现与对比

Java并发学习之线程状态及Thread常用方法详解

Java并发学习之定时任务的几种玩法与小结

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

推荐阅读更多精彩内容

  • 进程和线程 进程 所有运行中的任务通常对应一个进程,当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中...
    小徐andorid阅读 2,797评论 3 53
  • 登上朱雀山,一览众山小,那小的微妙,小的美好,小得错落有致,小得整整齐齐,站在巨人的肩上,一切都显得那么渺小。我则...
    扫云阅读 2,412评论 16 15
  • 如向日葵的仰望 你是我可望不可及的朝阳 每次日落 对你的仰望,愈发深沉 深入骨髓,沉进心海 如海浪追赶着天际 你是...
    茉莉的小茶馆阅读 235评论 0 0
  • 你的午休是什么样子?我先来说说我的午休是怎么过的吧! 吃完午饭,我就到自己的卧室玩了一会乐高积木,我拼了一个汽车 ...
    幸福一家曹硕阅读 98评论 0 1
  • 你仔细想想这个交易,只要你完成任务,你就可以升做3级情报员,每升一级加50%工资,你目前工资是3万,升50%就是4...
    快乐都市阅读 464评论 0 0