zoukankan      html  css  js  c++  java
  • 线程系列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进行限制,第二种方法进行了限制,线程互斥运行必然会出现相互等待的情况,而第一种方法则没有限制。

  • 相关阅读:
    从属性文件中读取配置
    Page Object Manager
    在Selenium中使用JavaScriptExecutor处理Ajax调用?
    wait
    常用操作
    Selenium收藏官方网址
    PageObject样例
    解决办法-错误:Access denied for user 'root'@'localhost'
    Struts2中的OGNL详解
    用C++,调用浏览器打开一个网页
  • 原文地址:https://www.cnblogs.com/aoshicangqiong/p/7711911.html
Copyright © 2011-2022 走看看