线程系列4--Java线程范围内的共享数据(一)
这张图片是我看传智播客的视频时的截屏,这个图片很直观的展示了线程范围内的数据共享。当同一个线程在执行三个不同业务模块时,这三个业务模块访问的数据是共享的。更直白的说,当一个执行线索在穿个每个业务模块时,这个执行线索在执行业务模块时,所调用的数据资源是共享的。线程范围内,是指同一个的执行线索的范围内。不同的线程是指不同的执行线索,不同的线程当然也就不属于同一个线程范围。

下面我们进入正题,依然是使用传智播客中的讲解内容作为今天的分析用例,挽起袖子开始撸代码。
public class ThreadScopeData {
private static Map<Thread,Integer> threadData = new HashMap<Thread, Integer>() ;
public static void main(String[] args) {
for(int i=0;i<2;i++){
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt();
System.out.println("线程名字:"+Thread.currentThread().getName()+",设置的data数据为:"+data);
threadData.put(Thread.currentThread(), data);
new Songzl().getData();
new Wangxl().getData();
}
}).start();
}
}
static class Songzl{
private void getData(){
int data = threadData.get(Thread.currentThread());
System.out.println("线程名字:"+Thread.currentThread().getName()+"业务方法songzl获取的data数据为:"+data);
}
}
static class Wangxl{
private void getData(){
int data = threadData.get(Thread.currentThread());
System.out.println("线程名字:"+Thread.currentThread().getName()+"业务方法wangxl获取的data数据为:"+data);
}
}
}
上面这个是张孝祥老师给出的实例代码,解决同一个线程范围内的数据共享问题。线程范围内的数据共享,可以理解为将数据单独复制出来一份,并且将数据和线程绑定起来。数据和线程被绑定在一起,被执行的模块都通过线程去寻找对应绑定的数据,那么取出来的数据必然是一直的。
下面这个方法是我个人写出来的,同样能实现线程内的数据共享:
public class ThreadScopeDataDemo {
private static int data = 0;
public static void main(String[] args) {
for(int i=0;i<2;i++){
new Thread(new Runnable() {
@Override
public void run() {
//使用类的字节码对象,作为同步锁
synchronized (ThreadScopeDataDemo.class) {
data = new Random().nextInt();
System.out.println("线程名字:"+Thread.currentThread().getName()+",设置的data数据为:"+data);
new Songzl().getData();
new Wangxl().getData();
}
}
}).start();
}
}
static class Songzl{
private void getData(){
System.out.println("线程名字:"+Thread.currentThread().getName()+"业务方法songzl获取的data数据为:"+data);
}
}
static class Wangxl{
private void getData(){
System.out.println("线程名字:"+Thread.currentThread().getName()+"业务方法wangxl获取的data数据为:"+data);
}
}
}
上面的代码同样可以实现线程范围内的数据共享,区别是没有使用map存放线程对象,而是使用同步锁的方式来实现。通过上面的代码我们可以更好的理解,为什么多线程的时候数据会取错,原因就是当cup执行的时候,在多个线程间切换运行,导致一个线程的业务没有执行完毕,就跳到了另个线程执行。我们将数据和线程绑定,就是为了避免较差执行,出现数据错乱的问题。我们加同步锁,同样也是保证,一个线程正常执行完毕后,再让另一个线程执行,这样也能保证同一个线程的执行范围内数据共享。但是从代码的角度分析,上面的俩种实现方法,第一种的性能应该高于第二种。因为第一种没有对cup进行限制,第二种方法进行了限制,线程互斥运行必然会出现相互等待的情况,而第一种方法则没有限制。
线程系列4--Java线程范围内的共享数据(一)的更多相关文章
- 【java线程系列】java线程系列之java线程池详解
一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在 ...
- 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型
关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...
- Java并发编程系列-(6) Java线程池
6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...
- Java并发编程系列-(7) Java线程安全
7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
- 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁
当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...
- 【阿里面试系列】Java线程的应用及挑战
文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关 ...
- 并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项
并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 线程池的缘由 java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的 ...
- java线程系列之三(线程协作)
本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...
- java多线程与线程并发四:线程范围内的共享数据
当多个线程操作同一个共有数据时,一个线程对共有数据的改变会影响到另一个线程.比如下面这个例子:两个线程调用同一个对象的的方法,一个线程的执行结果会影响另一个线程. package com.sky.th ...
随机推荐
- 服务端相关知识学习(一)之什么是zookeeper
什么是zookeeper zookeeper是分布式协调服务,可以在分布式系统中共享配置.协调锁资源.提供命名服务那分布式协调服务又是个什么东西呢?首先我们来看“协调”是什么意思.在一个并发的环境里, ...
- java中的运算符与表达式
运算符与表达式 运算符分类: 0.赋值运算符 = 1.算数运算符 + - * / % 2.比较运算符 < > == <= >= != 3.逻辑运算符 & | ! &am ...
- docker一键搭建Nginx+PHP环境(含自动部署命令)
文章的主要部分是一步一步的教程,文章的最后是我整理好的一键安装命令,自动下载并安装docker,构建镜像,启动容器集群(压缩包内注释覆盖范围达到80%) 大家可以看完教程亲自尝试下,也可以直接执行一键 ...
- linux tty终端个 pts伪终端 telnetd伪终端
转:http://blog.sina.com.cn/s/blog_735da7ae0102v2p7.html 终端tty.虚拟控制台.FrameBuffer的切换过程详解 Framebuffer Dr ...
- 2.Nginx基本配置
1. Nginx相关概念 代理服务器一般分为正向代理(通常直接称为代理服务器)和反向代理. 通常的代理服务器,只用于代理内部网络对Internet的连接请求,客户机必须指定代理服务器,并将本来要直接发 ...
- Linux rpm yum
RPM : 1 rpm -q 子选项 软件名 -a :列出已安装所有的软件包 -i :查看指定软件的详细信息 -l:查看指定软件的文件安装清单 -f:查看某个目录.文件是哪个包带来的 rpm -q ...
- shell脚本基础和grep文本处理工具企业应用1
bash特性及bash脚本编程初步: 用户要跟计算机交互就需要有终端,比如:显示器.键鼠等,在终端有附着的接口程序 GUI:KDE.GNome.Xfce CLI:/etc/shells bash ...
- Summer training #2
A:不管有没有负数 一顿操作之后肯定只有正数 又因为A=A-B 所以最大值是一直在减小的 所以一定有结果 B:..一开始以为求min操作数 WA了2发 直接求所有数的GCD如果所有数的GCD都不是1的 ...
- hutools之批量更新
public class HutoolTest { private static DataSource dataSource = DSFactory.get(); //读取默认路径下的配置文件,数据库 ...
- u-boot下的DM驱动模型 阶梯状 (转)
U-boot 下DM驱动模型的相关笔记要注意的关键两点: DM驱动模型的一般流程bind->ofdata_to_platdata(可选)->probe 启动,bind操作时单独完成的 ...