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

下面我们进入正题,依然是使用传智播客中的讲解内容作为今天的分析用例,挽起袖子开始撸代码。

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线程范围内的共享数据(一)的更多相关文章

  1. 【java线程系列】java线程系列之java线程池详解

    一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在 ...

  2. 【java线程系列】java线程系列之线程间的交互wait()/notify()/notifyAll()及生产者与消费者模型

    关于线程,博主写过java线程详解基本上把java线程的基础知识都讲解到位了,但是那还远远不够,多线程的存在就是为了让多个线程去协作来完成某一具体任务,比如生产者与消费者模型,因此了解线程间的协作是非 ...

  3. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

  4. Java并发编程系列-(7) Java线程安全

    7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...

  5. 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

    当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...

  6. 【阿里面试系列】Java线程的应用及挑战

    文章简介 上一篇文章[「阿里面试系列」搞懂并发编程,轻松应对80%的面试场景]我们了解了进程和线程的发展历史.线程的生命周期.线程的优势和使用场景,这一篇,我们从Java层面更进一步了解线程的使用.关 ...

  7. 并发编程系列:Java线程池的使用方式,核心运行原理、以及注意事项

    并发编程系列: 高并发编程系列:4种常用Java线程锁的特点,性能比较.使用场景 线程池的缘由 java中为了提高并发度,可以使用多线程共同执行,但是如果有大量线程短时间之内被创建和销毁,会占用大量的 ...

  8. java线程系列之三(线程协作)

    本文来自:高爽|Coder,原文地址:http://blog.csdn.net/ghsau/article/details/7433673,转载请注明. 上一篇讲述了线程的互斥(同步),但是在很多情况 ...

  9. java多线程与线程并发四:线程范围内的共享数据

    当多个线程操作同一个共有数据时,一个线程对共有数据的改变会影响到另一个线程.比如下面这个例子:两个线程调用同一个对象的的方法,一个线程的执行结果会影响另一个线程. package com.sky.th ...

随机推荐

  1. 深度:Hadoop对Spark五大维度正面比拼!

    每年,市场上都会出现种种不同的数据管理规模.类型与速度表现的分布式系统.在这些系统中,Spark和hadoop是获得最大关注的两个.然而该怎么判断哪一款适合你? 如果想批处理流量数据,并将其导入HDF ...

  2. mysql中取出的时间日期多个.0

    字段名称为 create_time 字段类型为 datetime 存储的内容为 2019-03-26 09:42:05 但是 通过mybatis取出来放到实体类里,数值就变成了 2019-03-26 ...

  3. Google 开源的 Python 命令行库:初探 fire

    作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...

  4. windows下修改vagrant虚拟机中的html ,通过nginx访问后不生效

    更改本地html文件,通过nginx配置的虚拟域名访问, 无论怎么修改内容,都不变化,即使我把内容删除一半,它显示的也是以前内容的一半,除非删除文件,才会从新生成. 解决办法 修改nginx.conf ...

  5. lumen时区

    今天用 Lumen 框架写代码时, 也是初次体验 Lumen, 遇到了一个问题, 从数据库里查出的时间比数据库里保存的 TIMESTAMP 时间慢了8个小时, 很明显这是一个时区设置的问题, 本以为可 ...

  6. Linux:rm可不可以实现删除所有文件,除了demo文件

    方法1: shopt -s extglob #开启扩展通配符 rm -rf !(demo) #删除除了demo的文件 方法2: find /test -not -name "demo&quo ...

  7. 从 Android 源码到 apk 的编译打包流程

    文中涉及到的工具所在目录:Android/sdk/build-tools.下面开始分解并逐步实现对源码的打包. 编译流程 1. 生成仅包含资源文件的 apk 包和 R.java 文件 根据资源文件和 ...

  8. layui 数据表格自适应高度

    添加css .layui-table-cell { height: inherit; } .layui-table-cell { height: inherit;}

  9. three.js之创建一条直线

    <!DOCTYPE html> <html> <head> <meta charset=utf-8> <title>My first thr ...

  10. Java语言基础(10)

    1 方法(三) 案例:Demo1 import java.util.Scanner; public class Demo1 { static int min(int num1,int num2){ i ...