`

转:ThreadLocal实现线程范围内的数据共享

    博客分类:
  • java
阅读更多

实现线程范围内的数据共享就是各自的线程管理各自线程上的数据,不被另外线程干扰。大个比方: 当第一个线程运行的时候往一集合里放一数据(比如是2),当第二个线程运行过来的时候往相同的集合里相同的位置上放了数据3,这时通常情况下是3将2覆盖掉了,然而在这里不是这样的,他们是两个不同的线程,不能有冲突,这要怎么解决呢? 有两种办法,使的当第一个线程再次运行都这里时,取出数据是2,当第二个线程也再次运行到这里时候取出数据是3, 这样取出的数据是刚开始放入的数据,没有产生冲突。

 

第一种方法:

使用Map

package cn.itcast.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadLocalShare {

	/**
	 * @param args
	 */
	//private static int data;
	private static Map shareData = new HashMap();
	public static void main(String[] args) {

		for (int i=0; i<2; i++) {
			new Thread(){
				public void run() {
					int data = new Random().nextInt();
					shareData.put(Thread.currentThread(), data);
					System.out.println(Thread.currentThread().getName() + " put data is " + data);
					System.out.println(Thread.currentThread().getName() + " A get data is " + new A().get());
					System.out.println(Thread.currentThread().getName() + " B get data is " + new B().get());
				}
			}.start();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}
	

	static class A {
		public  int get() {
			synchronized (ThreadLocalShare.class) {
				try {
					Thread.sleep(new Random().nextInt(100));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return (Integer)shareData.get(Thread.currentThread());
			}
		}
	}

	static class B {
		public  int get() {
			synchronized (ThreadLocalShare.class) {
				try {
					Thread.sleep(new Random().nextInt(100));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return (Integer)shareData.get(Thread.currentThread());
			}
		}
	}
	
}

 

第二种方法:

使用ThreadLocal类

 

package cn.itcast.thread;

import java.util.Random;

import cn.itcast.thread.ThreadLocalShare.A;
import cn.itcast.thread.ThreadLocalShare.B;

public class ThreadLocalShare2 {

	private static ThreadLocal shareData = new ThreadLocal();
	
	public static void main(String[] args) {
		for (int i=0; i<2; i++) {
			new Thread(){
				public void run() {
					int data = new Random().nextInt();
					//shareData.set(data);
					MyData.getInstance().setData(data);
					System.out.println(Thread.currentThread().getName() + " put data is " + data);
					System.out.println(Thread.currentThread().getName() + " A get data is " + new A().get());
					System.out.println(Thread.currentThread().getName() + " B get data is " + new B().get());
					System.out.println(Thread.currentThread().getName() + " C get data is " + new C().get());
				}
			}.start();
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	static class A {
		public  int get() {
			synchronized (ThreadLocalShare.class) {
				try {
					Thread.sleep(new Random().nextInt(100));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return MyData.getInstance().getData();
			}
		}
	}

	static class B {
		public  int get() {
			synchronized (ThreadLocalShare.class) {
				try {
					Thread.sleep(new Random().nextInt(100));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return MyData.getInstance().getData();
			}
		}
	}
	
	static class C {
		public  int get() {
			synchronized (ThreadLocalShare.class) {
				try {
					Thread.sleep(new Random().nextInt(100));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				return MyData.getInstance().getData();
			}
		}
	}
}

class MyData {
	private static ThreadLocal instanceHolder = new ThreadLocal();
	
	private int data;
	private static MyData instance = new MyData();
	
	private MyData() {}
	
	public static MyData getInstance() {
		MyData instance = (MyData) instanceHolder.get();
		if (instance == null) {
			instance = new MyData();
			instanceHolder.set(instance);
		}
		return instance;
	}
	
	public void setData(int data) {
		this.data = data;
	}
	
	public int getData() {
		return data;
	}

}

 

分享到:
评论

相关推荐

    Java多线程编程之ThreadLocal线程范围内的共享变量

    Java中的ThreadLocal是一种特殊类型的变量,它主要用于在多线程环境下提供线程范围内的局部变量。每个线程都拥有自己独立的ThreadLocal变量副本,互不影响。这与传统的全局变量不同,全局变量在所有线程间共享,可能...

    ThreadLocal和事务

    使用ThreadLocal来管理数据库连接,可以确保每个请求的生命周期内,连接只被该请求使用,避免了线程间的数据共享问题,提高了安全性。 接着,我们谈谈`c3p0`数据源。c3p0是一个开源的JDBC连接池,它实现了数据源和...

    Spring事务处理-ThreadLocal的使用

    这样,Spring可以在事务范围内正确地传播事务,即使在多线程环境下也能保证事务的正确性。 在Spring的`PlatformTransactionManager`接口中,`TransactionStatus`对象通常会用ThreadLocal来存储。当开始一个事务时,...

    多线程与多核编程文档

    - **线程局部变量**:ThreadLocal为每个线程提供独立的变量副本,避免了线程间的数据共享问题。 7. **案例分析**: - **Web服务器**:多线程处理客户端请求,提高服务器响应速度。 - **大数据处理**:利用多核...

    JDK5中的多线程并发库.doc

    在JDK5中,Java引入了一套强大的多线程并发库,极大地提升了多线程编程的效率和安全...而线程范围内的数据共享,如`ThreadLocal`,则常用于存储线程局部变量,保证了各个线程之间的数据隔离,避免了不必要的同步开销。

    java线程安全总结.doc

    4. **线程局部变量**:每个线程都有自己的副本,不会造成数据冲突,如`ThreadLocal`类。 ### 三、线程安全策略 1. **同步机制**:包括`synchronized`关键字、`Lock`接口(如`ReentrantLock`)以及`java.util....

    java thread的教程

    - **ThreadLocal类**:为每个线程提供一个独立的变量副本,避免线程间的直接数据共享。 **线程池:** 线程池是一种管理线程生命周期的机制,它可以复用预先创建好的线程,避免频繁创建和销毁线程所带来的性能开销。...

    张孝祥Java多线程与并发库高级应用笔记

    - **概念**:线程范围内共享变量是指在线程间共享的数据,需小心处理以避免竞态条件和数据不一致性。 - **作用**:允许线程间通信和协作,但需采用适当的同步机制(如`synchronized`关键字、`Lock`接口)以确保数据...

    JDK5中的多线程并发库

    5. **线程范围内共享数据**: - **应用场景**:比如银行转账,转入和转出需要共享数据。 - **解决方案**:可以使用自定义`Map`以`Thread`对象为Key保存数据,或者使用`ThreadLocal`,它为每个线程维护独立的变量...

    Java多线程编程总结

    - 线程总是隶属于某个进程,同一进程内的多个线程共享内存空间。 2. **Java中的线程** - 在Java中,“线程”有两层含义: - `java.lang.Thread` 类的一个实例。 - 线程的执行过程。 - 使用 `java.lang.Thread`...

    java线程同步

    Java线程同步是多线程编程中的一个重要概念,它用于解决在并发环境下多个线程对共享资源的访问问题,以防止数据的不一致性。在Java中,线程同步的机制主要包括锁、同步块、同步方法、volatile关键字以及线程通信(如...

    java线程.part001

    - ThreadLocal:为每个线程创建一个独立的变量副本,避免了线程间的共享和同步问题。 4. **线程优先级** Java中的线程有不同的优先级,范围从MIN_PRIORITY(1)到MAX_PRIORITY(10),默认优先级是NORM_PRIORITY...

    1工作临时-servlet 多线程问题

    如果需要保存状态,使用线程安全的数据结构或使用请求范围内的变量。 2. 使用Java的并发工具类,如`java.util.concurrent`包中的`Semaphore`, `CountDownLatch`, `CyclicBarrier`等,以协调线程的执行。 3. 考虑...

    java线程编程资料

    - **synchronized关键字**:用于控制多线程对共享资源的访问,防止数据不一致。 - **Lock接口**:提供比synchronized更细粒度的锁控制,如ReentrantLock。 - **volatile关键字**:确保共享变量的可见性和有序性,...

    基于Java实现的多线程与线程安全实践-基于Http协议的断点续传.zip

    服务器接收到这个请求后,只会发送指定范围内的数据,这样就可以实现断点续传。 在Java中,我们可以使用HttpURLConnection或者HttpClient库来发送带有Range头的HTTP请求。例如,当下载中断时,记录下已下载的文件...

    Java多线程

    线程总是属于某个进程,并且同一进程内的多个线程共享该进程的内存资源。 **2. Java中的线程** 在Java中,“线程”主要涉及两个方面: - **java.lang.Thread类的实例**:表示线程对象,拥有自己的变量和方法,...

    javaWeb实现事务1

    由于每个DAO都在同一个线程中运行,因此可以通过`ConnectionContext.getSingleton().get()`获取并使用已经绑定的连接,所有这些操作都在同一个事务范围内。 4. **事务提交或回滚**: 如果业务逻辑执行成功,`...

    java多线程

    - **ThreadLocal**:为每个线程提供独立的变量副本,避免数据冲突。 3. **线程池** - **ExecutorService**:Java并发框架的核心接口,用于管理线程池。 - **ThreadPoolExecutor**:具体的线程池实现,可配置核心...

Global site tag (gtag.js) - Google Analytics