zoukankan      html  css  js  c++  java
  • 并发编程基础之ThreadLocal

    一:概念

    在多线程并发访问的情况下,为了解决线程安全,一般我们会使用synchronized关键字,如果并发访问量不是很大,可以使用synchronized,

    但是如果数据量比较大,我们可以考虑使用ThreadLocal,顾名思义,就是线程的本地存储,对于类中的成员变量,如果多个线程同时访问

    就会存在线程安全问题,ThreadLocal提供给我们不同于synchronized的另外一种思路,就是把变量值在每个线程存储副本

    如下示例:

    /**
     * 
     */
    package com.hlcui.main;
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * @author Administrator
     *
     */
    public class ThreadLocalDemo {
    	
    	//保留变量在线程中的副本
    	private ThreadLocal<String> threadLocal = new ThreadLocal<String>();
    	
    	private void set(String name) {
    		threadLocal.set(name);
    	}
    	
    	private String get() {
    		return threadLocal.get();
    	}
    	
    	public static void main(String[] args) {
    		final ThreadLocalDemo demo = new ThreadLocalDemo();
    		
    		ExecutorService executors = Executors.newFixedThreadPool(2);
    		executors.execute(new Runnable() {
    			@Override
    			public void run() {
    				demo.set("tom");
    				String threadName = Thread.currentThread().getName();
    				System.out.println(threadName+":::"+demo.get());
    			}
    		});
    		
    		executors.execute(new Runnable() {
    			@Override
    			public void run() {
    				demo.set("jack");
    				String threadName = Thread.currentThread().getName();
    				System.out.println(threadName+":::"+demo.get());
    			}
    		});
    		
    		executors.shutdown();
    	}
    }
    

      

    运行结果:

    pool-1-thread-1:::tom
    pool-1-thread-2:::jack
    

      

    通过结果可以看出同一个实例的同一个方法,不同的线程获取的结果是不一样的。

    示例二:

    测试5个线程计数:

    /**
     * 
     */
    package com.hlcui.main;
    
    import java.util.Random;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.TimeUnit;
    
    /**
     * @author Administrator
     *
     */
    public class ThreadDemo2 {
    	public static void main(String[] args) {
    		ExecutorService executors = Executors.newFixedThreadPool(5);
    		for (int i = 0; i < 5; i++) {
    			executors.execute(new ThreadHolder(i));
    		}
    		try {
    			TimeUnit.SECONDS.sleep(3);
    		} catch (InterruptedException e) {
    			e.printStackTrace();
    		}
    		executors.shutdown();
    	}
    
    }
    
    class ThreadHolder implements Runnable {
    
    	private final int id;
    
    	ThreadHolder(int i) {
    		this.id = i;
    	}
    
    	private static ThreadLocal<Integer> tl = new ThreadLocal<Integer>() {
    		Random r = new Random(47);
    		public synchronized Integer initialValue() {
    			return r.nextInt(100);
    		}
    	};
    
    	public static void increment() {
    		tl.set(tl.get() + 1);
    	}
    
    	@Override
    	public void run() {
    		System.out.println(this);
    		ThreadHolder.increment();
    		System.out.println(this);
    	}
    	
    	public String toString() {
    		return "id:::"+id+", "+tl.get();
    	}
    
    }
    

      

    运行结果:

    id:::0, 58
    id:::1, 55
    id:::2, 93
    id:::0, 59
    id:::2, 94
    id:::1, 56
    id:::3, 61
    id:::3, 62
    id:::4, 61
    id:::4, 62
    

      

  • 相关阅读:
    Linux:备份
    在 Cordova/Phonegap for Android 中包含中文文件名的页面
    jQuery插件开发
    为Google Reader守夜。。。
    冒泡排序
    无题六月
    XXX读后感
    KL25的AD采集操作
    工作流--JBPM简介及开发环境搭建
    内存错误:CRT detected that the application wrote to memory after end of heap buffer
  • 原文地址:https://www.cnblogs.com/warrior4236/p/7533387.html
Copyright © 2011-2022 走看看