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
    

      

  • 相关阅读:
    cmanformat
    mysql-sql语言参考
    jQuery 判断多个 input checkbox 中至少有一个勾选
    Java实现 蓝桥杯 算法提高 计算行列式
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 数独游戏
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
    Java实现 蓝桥杯 算法提高 成绩排序2
  • 原文地址:https://www.cnblogs.com/warrior4236/p/7533387.html
Copyright © 2011-2022 走看看