第五章--Java多线程和并发编程 第三节--Java多线程信息共享

多线程信息共享(1)

线程类:

---- 通过继承Thread或实现Runnable

---- 通过start方法,调用run方法,run方法工作

---- 线程run结束之后,线程退出

粗粒度:子线程与子线程之间,子线程和main线程之间缺乏交流(之前的多线程就是一中粗粒度的执行模式)

细粒度:线程之间有信息交流通讯(细粒度的编程模式)

对于细粒度的执行模式,需要注意:

(1)可以通过共享变量达到信息共享

(2)JDK原生库暂时不支持点对点发送消息(类似MPI并行库直接发送消息)

MPI并行库是一个C / C++的并行库,可以支持像 线程0线程1发送一封消息,或者说线程0向所有的线程群发一条消息,像这种点对点的消息,Java还不支持

多线程信息共享(2):

----通过共享变量在多个线程中共享信息

(1)static变量(是这个类所有的对象,都共享的一个变量)

(2)同一个Runnable类的成员变量

这样的共享变量在多个线程中实际上就是一个拷贝对象,理解成下图,它们要用数据,直接从内存里面拿,拿到在自己的线程里去运算

注意:如果一个线程类继承了Thread类,那么它的信息共享只能通过static来,而不能通过普通的成员变量(线程类中的成员变量),普通的成员变量达不到信息共享的目的

多线程信息共享(3):

---- 多线程信息共享存在的两个问题:

(1)工作缓存副本:每个线程都有自己的工作缓存,这个线程需要数据的时候,他是从内存里面加载完数据,放到工作缓存里面来。现在有一个线程把工作缓存里面的值给修改了,这里修改好的数据其他线程没有看到,他们还是用自己的工作缓存里面的数据,进行运算,这就导致每个线程的工作缓存里面并没有反映出最新的变量是多少,大家用的都是前一刻的变量的值,而不是最新的值,所以导致数据不一致的问题

(2)关键步骤缺乏加锁限制:关键步骤,即比如对重要变量做操作如买火车票问题中的票数。加锁限制,简单地说就是这样的一个关键变量,当一个线程去修改它的时候,要限制一个只能有一个线程去修改它,不能多个人同时修改它,否则修改会引起错乱

下图是Java多线程内存模型(中间是JVM控制)

---- 原子性操作:只有一个操作,原子已经不可再分了。比如i++就不是原子性操作,(在Java的内存模型里面)分成几个步骤执行的:

(1)读取主存RAM中的i(正本,正式的值)到工作缓存(副本,复制品)中去

(2)每个CPU执行(副本)i+1操作

(3)CPU将结果写入到缓存(副本)中

(4)数据从公座缓存(副本)刷新到主存(正本)中

多线程信息共享(4):

---- 变量副本问题的解决方法:

(1)采用 volatile 关键字修饰变量,保证不同线程对共享变量操作时都是可见的:我们在一个线程的工作缓存中修改了一个变量的值,结果其他线程的工作缓存中的值没有刷新。volatile关键字可以帮助我们,一旦一个变量在工作缓存区里面被修改了,其他的线程也马上也能看到

(2)关键步骤加锁限制

---- 互斥:某一个线程运行一个代码段(关键区),其他线程不能同时运行这个代码段

---- 多个线程的运行,必须按照某一种规定的先后顺序来运行

---- 互斥是同步的一种特例,是同步里面最简单的一种方式

---- 互斥的关键字是synchronized:

                    synchronized可以修饰代码块 / 函数,只能一个线程进入

                    synchronized加大性能负担,但是使用简便

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值